Commit 53e7f518 authored by Sam Saffron's avatar Sam Saffron

remove TVP ... was a bad idea, too slow

parent 19a5975a
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
using System.Reflection; using System.Reflection;
using Microsoft.SqlServer.Server; using Microsoft.SqlServer.Server;
using System.Dynamic; using System.Dynamic;
using System.Collections;
namespace SqlMapper namespace SqlMapper
{ {
...@@ -239,7 +240,7 @@ private static IDataReader GetReader<T>(IDbConnection cnn, SqlTransaction tranac ...@@ -239,7 +240,7 @@ private static IDataReader GetReader<T>(IDbConnection cnn, SqlTransaction tranac
foreach (var info in paramInfo) foreach (var info in paramInfo)
{ {
var param = new SqlParameter("@" + info.Name, info.Type); var param = new SqlParameter("@" + info.Name, info.Type);
cmd.Parameters.Add(param);
param.Value = info.Val ?? DBNull.Value; param.Value = info.Val ?? DBNull.Value;
param.Direction = ParameterDirection.Input; param.Direction = ParameterDirection.Input;
...@@ -250,43 +251,34 @@ private static IDataReader GetReader<T>(IDbConnection cnn, SqlTransaction tranac ...@@ -250,43 +251,34 @@ private static IDataReader GetReader<T>(IDbConnection cnn, SqlTransaction tranac
if (info.Type == SqlDbType.Structured) if (info.Type == SqlDbType.Structured)
{ {
List<SqlDataRecord> items = new List<SqlDataRecord>();
SqlMetaData[] metadata; // initially we tried TVP, however it performs quite poorly.
// keep in mind SQL support up to 2000 params easily in sp_executesql, needing more is rare
var intList = info.Val as IEnumerable<int>; var list = info.Val as IEnumerable;
if (intList != null) var count = 0;
{
metadata = new[] { new SqlMetaData("Id", SqlDbType.Int) }; if (list != null)
foreach (int id in intList) {
foreach (var item in list)
{ {
SqlDataRecord rec = new SqlDataRecord(metadata); count++;
rec.SetInt32(0, id); cmd.Parameters.Add(new SqlParameter("@" + info.Name + count, item));
items.Add(rec);
} }
param.TypeName = "int_list";
cmd.CommandText = cmd.CommandText.Replace("@" + info.Name,
"(" + string.Join(
",", Enumerable.Range(1, count).Select(i => "@" + info.Name + i)
) + ")");
} }
else else
{ {
var strList = info.Val as IEnumerable<string>; throw new NotImplementedException();
if (strList != null)
{
metadata = new[] { new SqlMetaData("Name", SqlDbType.NVarChar, 4000) };
foreach (var str in strList)
{
SqlDataRecord rec = new SqlDataRecord(metadata);
rec.SetString(0, str);
items.Add(rec);
}
param.TypeName = "string_list";
}
else
{
throw new NotImplementedException();
}
} }
}
param.Direction = ParameterDirection.Input; else
param.Value = items; {
cmd.Parameters.Add(param);
} }
} }
} }
......
...@@ -56,7 +56,7 @@ public void SelectListInt() ...@@ -56,7 +56,7 @@ public void SelectListInt()
public void PassInIntArray() public void PassInIntArray()
{ {
connection.ExecuteMapperQuery<int>("select * from @Ids", new { Ids = new int[] { 1, 2, 3 }.AsEnumerable() }) connection.ExecuteMapperQuery<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 }.AsEnumerable() })
.IsSequenceEqual(new[] { 1, 2, 3 }); .IsSequenceEqual(new[] { 1, 2, 3 });
} }
...@@ -119,7 +119,7 @@ public void TestExpando() ...@@ -119,7 +119,7 @@ public void TestExpando()
public void TestStringList() public void TestStringList()
{ {
connection.ExecuteMapperQuery<string>("select * from @strings", new {strings = new[] {"a","b","c"}}) connection.ExecuteMapperQuery<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new {strings = new[] {"a","b","c"}})
.IsSequenceEqual(new[] {"a","b","c"}); .IsSequenceEqual(new[] {"a","b","c"});
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment