提交 885a8d46 编写于 作者: M Marc Gravell

Provide support for OleDB / anonymous sql parameters

上级 8f017a25
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NuGet.CommandLine" version="2.0.40001" />
<package id="NuGet.CommandLine" version="2.5.0" />
<package id="NuGet.CommandLine" version="2.0.40001" />
</packages>
\ No newline at end of file
......@@ -683,7 +683,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, string sql, objec
/// <returns>Number of rows affected</returns>
public static int Execute(
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
......@@ -741,35 +741,40 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param) {
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param)
{
return Query(cnn, sql, param, null, true, null, null);
}
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction) {
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction)
{
return Query(cnn, sql, param, transaction, true, null, null);
}
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, CommandType? commandType) {
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, CommandType? commandType)
{
return Query(cnn, sql, param, null, true, null, commandType);
}
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType? commandType) {
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType? commandType)
{
return Query(cnn, sql, param, transaction, true, null, commandType);
}
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
public static IEnumerable<IDictionary<string,object>> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType) {
public static IEnumerable<IDictionary<string, object>> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType)
{
return Query<IDictionary<string, object>>(cnn, sql, param, transaction, buffered, commandTimeout, commandType);
}
#endif
......@@ -783,7 +788,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
/// </returns>
public static IEnumerable<T> Query<T>(
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null
#endif
......@@ -798,7 +803,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
/// </summary>
public static GridReader QueryMultiple(
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
......@@ -909,7 +914,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>(
#if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif
......@@ -937,7 +942,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(
#if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif
......@@ -966,7 +971,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TReturn>(
#if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif
......@@ -1247,7 +1252,7 @@ private static CacheInfo GetCacheInfo(Identity identity)
#endif
else
{
info.ParamReader = CreateParamInfoGenerator(identity, false);
info.ParamReader = CreateParamInfoGenerator(identity, false, true);
}
}
SetQueryCache(identity, info);
......@@ -1265,7 +1270,7 @@ private static CacheInfo GetCacheInfo(Identity identity)
return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing);
}
#else
if(type.IsAssignableFrom(typeof(Dictionary<string,object>)))
if (type.IsAssignableFrom(typeof(Dictionary<string, object>)))
{
return GetDictionaryDeserializer(reader, startBound, length, returnNullIfFirstMissing);
}
......@@ -1831,13 +1836,22 @@ private static IEnumerable<PropertyInfo> FilterParameters(IEnumerable<PropertyIn
return parameters.Where(p => Regex.IsMatch(sql, @"[?@:]" + p.Name + "([^a-zA-Z0-9_]+|$)", RegexOptions.IgnoreCase | RegexOptions.Multiline));
}
// look for ? / @ / : *by itself*
static readonly Regex smellsLikeOleDb = new Regex(@"(?<![a-zA-Z0-9_])[?@:](?![a-zA-Z0-9_])", RegexOptions.Compiled);
/// <summary>
/// Internal use only
/// </summary>
public static Action<IDbCommand, object> CreateParamInfoGenerator(Identity identity, bool checkForDuplicates)
public static Action<IDbCommand, object> CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused)
{
Type type = identity.parametersType;
bool filterParams = identity.commandType.GetValueOrDefault(CommandType.Text) == CommandType.Text;
bool filterParams = false;
if (removeUnused && identity.commandType.GetValueOrDefault(CommandType.Text) == CommandType.Text)
{
filterParams = !smellsLikeOleDb.IsMatch(identity.sql);
}
var dm = new DynamicMethod(string.Format("ParamInfo{0}", Guid.NewGuid()), null, new[] { typeof(IDbCommand), typeof(object) }, type, true);
var il = dm.GetILGenerator();
......@@ -1851,11 +1865,63 @@ private static IEnumerable<PropertyInfo> FilterParameters(IEnumerable<PropertyIn
il.Emit(OpCodes.Ldarg_0); // stack is now [command]
il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty("Parameters").GetGetMethod(), null); // stack is now [parameters]
IEnumerable<PropertyInfo> props = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0).OrderBy(p => p.Name);
var propsArr = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0).ToArray();
var ctors = type.GetConstructors();
ParameterInfo[] ctorParams;
IEnumerable<PropertyInfo> props = null;
// try to detect tuple patterns, e.g. anon-types, and use that to choose the order
// otherwise: alphabetical
if (ctors.Length == 1 && propsArr.Length == (ctorParams = ctors[0].GetParameters()).Length)
{
// check if reflection was kind enough to put everything in the right order for us
bool ok = true;
for (int i = 0; i < propsArr.Length; i++)
{
if (!string.Equals(propsArr[i].Name, ctorParams[i].Name, StringComparison.InvariantCultureIgnoreCase))
{
ok = false;
break;
}
}
if(ok)
{
// pre-sorted; the reflection gods have smiled upon us
props = propsArr;
}
else { // might still all be accounted for; check the hard way
var positionByName = new Dictionary<string,int>(StringComparer.InvariantCultureIgnoreCase);
foreach(var param in ctorParams)
{
positionByName[param.Name] = param.Position;
}
if (positionByName.Count == propsArr.Length)
{
int[] positions = new int[propsArr.Length];
ok = true;
for (int i = 0; i < propsArr.Length; i++)
{
int pos;
if (!positionByName.TryGetValue(propsArr[i].Name, out pos))
{
ok = false;
break;
}
positions[i] = pos;
}
if (ok)
{
Array.Sort(positions, propsArr);
props = propsArr;
}
}
}
}
if(props == null) props = propsArr.OrderBy(x => x.Name);
if (filterParams)
{
props = FilterParameters(props, identity.sql);
}
foreach (var prop in props)
{
if (filterParams)
......@@ -2154,7 +2220,7 @@ public static void SetTypeMap(Type type, ITypeMap map)
/// <returns></returns>
public static Func<IDataReader, object> GetTypeDeserializer(
#if CSHARP30
Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing
Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing
#else
Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false
#endif
......@@ -2896,7 +2962,10 @@ partial class ParamInfo
/// <summary>
/// construct a dynamic parameter bag
/// </summary>
public DynamicParameters() { }
public DynamicParameters()
{
RemoveUnused = true;
}
/// <summary>
/// construct a dynamic parameter bag
......@@ -2904,6 +2973,7 @@ partial class ParamInfo
/// <param name="template">can be an anonymous type or a DynamicParameters bag</param>
public DynamicParameters(object template)
{
RemoveUnused = true;
AddDynamicParams(template);
}
......@@ -2914,7 +2984,7 @@ public DynamicParameters(object template)
/// <param name="param"></param>
public void AddDynamicParams(
#if CSHARP30
object param
object param
#else
dynamic param
#endif
......@@ -2976,7 +3046,7 @@ dynamic param
/// <param name="size"></param>
public void Add(
#if CSHARP30
string name, object value, DbType? dbType, ParameterDirection? direction, int? size
string name, object value, DbType? dbType, ParameterDirection? direction, int? size
#else
string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null
#endif
......@@ -3005,6 +3075,11 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Id
AddParameters(command, identity);
}
/// <summary>
/// If true, the command-text is inspected and only values that are clearly used are included on the connection
/// </summary>
public bool RemoveUnused { get; set; }
/// <summary>
/// Add all the parameters needed to the command just before it executes
/// </summary>
......@@ -3023,7 +3098,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
if (!paramReaderCache.TryGetValue(newIdent, out appender))
{
appender = SqlMapper.CreateParamInfoGenerator(newIdent, true);
appender = SqlMapper.CreateParamInfoGenerator(newIdent, true, RemoveUnused);
paramReaderCache[newIdent] = appender;
}
}
......
......@@ -78,7 +78,7 @@ internal class SomaConfig : Soma.Core.MsSqlConfig
{
public override string ConnectionString
{
get { return Program.connectionString; }
get { return Program.ConnectionString; }
}
public override void Log(Soma.Core.PreparedStatement preparedStatement)
......@@ -134,17 +134,17 @@ public void Run(int iterations)
var mapperConnection3 = Program.GetOpenConnection();
tests.Add(id => mapperConnection2.Get<Post>(id), "Dapper.Cotrib");
var massiveModel = new DynamicModel(Program.connectionString);
var massiveModel = new DynamicModel(Program.ConnectionString);
var massiveConnection = Program.GetOpenConnection();
tests.Add(id => massiveModel.Query("select * from Posts where Id = @0", massiveConnection, id).First(), "Dynamic Massive ORM Query");
// PetaPoco test with all default options
var petapoco = new PetaPoco.Database(Program.connectionString, "System.Data.SqlClient");
var petapoco = new PetaPoco.Database(Program.ConnectionString, "System.Data.SqlClient");
petapoco.OpenSharedConnection();
tests.Add(id => petapoco.Fetch<Post>("SELECT * from Posts where Id=@0", id), "PetaPoco (Normal)");
// PetaPoco with some "smart" functionality disabled
var petapocoFast = new PetaPoco.Database(Program.connectionString, "System.Data.SqlClient");
var petapocoFast = new PetaPoco.Database(Program.ConnectionString, "System.Data.SqlClient");
petapocoFast.OpenSharedConnection();
petapocoFast.EnableAutoSelect = false;
petapocoFast.EnableNamedParams = false;
......@@ -188,7 +188,7 @@ public void Run(int iterations)
tests.Add(id => db1.SetCommand("select * from Posts where Id = @id", db1.Parameter("id", id)).ExecuteList<Post>(), "BLToolkit");
// Simple.Data
var sdb = Simple.Data.Database.OpenConnection(Program.connectionString);
var sdb = Simple.Data.Database.OpenConnection(Program.ConnectionString);
tests.Add(id => sdb.Posts.FindById(id), "Simple.Data");
// Soma
......
......@@ -28,11 +28,12 @@ class Post
class Program
{
public static readonly string connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True";
public const string ConnectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True",
OleDbConnectionString = "Provider=SQLOLEDB;Data Source=.;Initial Catalog=tempdb;Integrated Security=SSPI";
public static SqlConnection GetOpenConnection()
{
var connection = new SqlConnection(connectionString);
var connection = new SqlConnection(ConnectionString);
connection.Open();
return connection;
}
......
......@@ -79,10 +79,12 @@ public void TestMultiMapWithConstructor()
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')";
connection.Execute(createSql);
try
{
string sql = @"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
PostWithConstructor[] data = connection.Query<PostWithConstructor, UserWithConstructor, PostWithConstructor>(sql, (post, user) => { post.Owner = user; return post;}).ToArray();
PostWithConstructor[] data = connection.Query<PostWithConstructor, UserWithConstructor, PostWithConstructor>(sql, (post, user) => { post.Owner = user; return post; }).ToArray();
var p = data.First();
p.FullContent.IsEqualTo("Sams Post1");
......@@ -91,9 +93,12 @@ public void TestMultiMapWithConstructor()
p.Owner.Ident.IsEqualTo(99);
data[2].Owner.IsNull();
}
finally
{
connection.Execute("drop table #Users drop table #Posts");
}
}
class MultipleConstructors
......@@ -159,7 +164,7 @@ public NoDefaultConstructor(int a1, int? b1, float f1, string s1, Guid G1)
public void TestNoDefaultConstructor()
{
var guid = Guid.NewGuid();
NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select CAST(NULL AS integer) A1, CAST(NULL AS integer) b1, CAST(NULL AS real) f1, 'Dapper' s1, G1 = @id", new { Id = guid }).First();
NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select CAST(NULL AS integer) A1, CAST(NULL AS integer) b1, CAST(NULL AS real) f1, 'Dapper' s1, G1 = @id", new { id = guid }).First();
nodef.A.IsEqualTo(0);
nodef.B.IsEqualTo(null);
nodef.F.IsEqualTo(0);
......@@ -315,6 +320,8 @@ public void PassInEmptyIntArray()
public void TestSchemaChanged()
{
connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')");
try
{
var d = connection.Query<Dog>("select * from #dog").Single();
d.Name.IsEqualTo("Alf");
d.Age.IsEqualTo(1);
......@@ -322,12 +329,18 @@ public void TestSchemaChanged()
d = connection.Query<Dog>("select * from #dog").Single();
d.Name.IsNull();
d.Age.IsEqualTo(1);
}
finally
{
connection.Execute("drop table #dog");
}
}
public void TestSchemaChangedMultiMap()
{
connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')");
try
{
var tuple = connection.Query<Dog, Dog, Tuple<Dog, Dog>>("select * from #dog d1 join #dog d2 on 1=1", (d1, d2) => Tuple.Create(d1, d2), splitOn: "Age").Single();
tuple.Item1.Name.IsEqualTo("Alf");
......@@ -342,9 +355,12 @@ public void TestSchemaChangedMultiMap()
tuple.Item1.Age.IsEqualTo(1);
tuple.Item2.Name.IsNull();
tuple.Item2.Age.IsEqualTo(1);
}
finally
{
connection.Execute("drop table #dog");
}
}
public void TestReadMultipleIntegersWithSplitOnAny()
{
......@@ -404,7 +420,7 @@ public void CheckComplexConcat()
string term = "F"; // the term the user searched for
connection.Execute(@"create table #users16726709 (first_name varchar(200), last_name varchar(200))
insert #users16726709 values ('Fred','Bloggs') insert #users16726709 values ('Tony','Farcus') insert #users16726709 values ('Albert','Tenof')");
insert #users16726709 values ('Fred','Bloggs') insert #users16726709 values ('Tony','Farcus') insert #users16726709 values ('Albert','TenoF')");
// Using Dapper
connection.Query(end_wildcard, new { search_term = term }).Count().IsEqualTo(2);
......@@ -462,7 +478,7 @@ public class Dog
public void TestExtraFields()
{
var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { Id = guid });
var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { id = guid });
dog.Count()
.IsEqualTo(1);
......@@ -474,6 +490,20 @@ public void TestExtraFields()
.IsEqualTo(guid);
}
// see http://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?",
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
public void TestStrongType()
{
......@@ -542,11 +572,18 @@ public void TestExecuteCommandWithHybridParameters()
public void TestExecuteMultipleCommand()
{
connection.Execute("create table #t(i int)");
try
{
int tally = connection.Execute(@"insert #t (i) values(@a)", new[] { new { a = 1 }, new { a = 2 }, new { a = 3 }, new { a = 4 } });
int sum = connection.Query<int>("select sum(i) from #t drop table #t").First();
int sum = connection.Query<int>("select sum(i) from #t").First();
tally.IsEqualTo(4);
sum.IsEqualTo(10);
}
finally
{
connection.Execute("drop table #t");
}
}
class Student
{
......@@ -557,15 +594,22 @@ class Student
public void TestExecuteMultipleCommandStrongType()
{
connection.Execute("create table #t(Name nvarchar(max), Age int)");
try
{
int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student>
{
new Student{Age = 1, Name = "sam"},
new Student{Age = 2, Name = "bob"}
});
int sum = connection.Query<int>("select sum(Age) from #t drop table #t").First();
int sum = connection.Query<int>("select sum(Age) from #t").First();
tally.IsEqualTo(2);
sum.IsEqualTo(3);
}
finally
{
connection.Execute("drop table #t");
}
}
public void TestExecuteMultipleCommandObjectArray()
{
......@@ -591,7 +635,7 @@ class TestObj
public int _priv;
private int Priv { set { _priv = value; } }
private int PrivGet { get { return _priv;} }
private int PrivGet { get { return _priv; } }
}
public void TestSetInternal()
......@@ -712,9 +756,10 @@ public void TestMultiMap()
insert #Posts values(3, null, 'no ones post')
";
connection.Execute(createSql);
try
{
var sql =
@"select * from #Posts p
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
......@@ -727,9 +772,12 @@ public void TestMultiMap()
p.Owner.Id.IsEqualTo(99);
data[2].Owner.IsNull();
}
finally
{
connection.Execute("drop table #Users drop table #Posts");
}
}
......@@ -1592,12 +1640,13 @@ public void TestMultiMapThreeTypesWithGridReader()
insert #Comments values(1, 1, 'Comment 1')";
connection.Execute(createSql);
try
{
var sql = @"SELECT p.* FROM #Posts p
select p.*, u.Id, u.Name + '0' Name, c.Id, c.CommentData from #Posts p
left join #Users u on u.Id = p.OwnerId
left join #Comments c on c.postId = p.Id
left join #Comments c on c.PostId = p.Id
where p.Id = 1
Order by p.Id";
......@@ -1610,9 +1659,12 @@ public void TestMultiMapThreeTypesWithGridReader()
post2.Comment.Id.IsEqualTo(1);
post2.Owner.Id.IsEqualTo(99);
}
finally
{
connection.Execute("drop table #Users drop table #Posts drop table #Comments");
}
}
public class DbParams : Dapper.SqlMapper.IDynamicParameters, IEnumerable<IDbDataParameter>
{
......@@ -1656,7 +1708,8 @@ public void TestReadDynamicWithGridReader()
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')";
try
{
connection.Execute(createSql);
var sql = @"SELECT * FROM #Users ORDER BY Id
......@@ -1672,9 +1725,12 @@ public void TestReadDynamicWithGridReader()
((int)users.First().Id).IsEqualTo(2);
((int)posts.First().Id).IsEqualTo(3);
}
finally
{
connection.Execute("drop table #Users drop table #Posts");
}
}
public void TestDynamicParamNullSupport()
{
......@@ -2081,7 +2137,8 @@ public void TestReaderWhenResultsChange()
obj4.X.IsEqualTo(1);
obj4.Y.IsEqualTo(1);
obj4.Z.IsEqualTo(2);
} finally
}
finally
{
connection.Execute("drop table #ResultsChange;drop table #ResultsChange2;");
}
......@@ -2324,11 +2381,13 @@ public void TestMultiSelectWithSomeEmptyGrids()
var two = reader.Read<int>().ToArray();
var three = reader.Read<int>().ToArray();
var four = reader.Read<int>().ToArray();
try { // only returned four grids; expect a fifth read to fail
try
{ // only returned four grids; expect a fifth read to fail
reader.Read<int>();
throw new InvalidOperationException("this should not have worked!");
}
catch (ObjectDisposedException ex) { // expected; success
catch (ObjectDisposedException ex)
{ // expected; success
ex.Message.IsEqualTo("The reader has been disposed; this can happen after all data has been consumed\r\nObject name: 'Dapper.SqlMapper+GridReader'.");
}
......@@ -2345,7 +2404,7 @@ public void TestDynamicMutation()
{
var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single();
((int)obj.a).IsEqualTo(1);
IDictionary<string,object> dict = obj;
IDictionary<string, object> dict = obj;
Assert.Equals(3, dict.Count);
Assert.IsTrue(dict.Remove("a"));
Assert.IsFalse(dict.Remove("d"));
......@@ -2524,7 +2583,7 @@ public void TestIssue17648290()
var p = new DynamicParameters();
int code = 1, getMessageControlId = 2;
p.Add("@Code", code);
p.Add("@MessageControlId", getMessageControlId);
p.Add("@MessageControlID", getMessageControlId);
p.Add("@SuccessCode", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@ErrorDescription", dbType: DbType.String, direction: ParameterDirection.Output, size: 255);
connection.Execute(@"CREATE PROCEDURE #up_MessageProcessed_get
......
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Npgsql</id>
<version>2.0.11</version>
<title>Npgsql</title>
<authors>Jon Asher, Brar Piening, Chris Morgan, Dave Page, Federico Di Gregorio, Francisco Figueiredo jr., Hiroshi Saito, Josh Cooley, Jon Hanna</authors>
<owners>Jon Asher, Brar Piening, Chris Morgan, Dave Page, Federico Di Gregorio, Francisco Figueiredo jr., Hiroshi Saito, Josh Cooley, Jon Hanna</owners>
<licenseUrl>http://www.opensource.org/licenses/bsd-license.php</licenseUrl>
<projectUrl>http://pgfoundry.org/projects/npgsql/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Npgsql is a .Net data provider for Postgresql. It allows any program developed for .Net framework to access database server. It is implemented in 100% C# code. Works with Postgresql 7.x and 8.x.</description>
<summary>Npgsql is a .Net data provider for Postgresql.</summary>
<tags>Npgsql postgres data database</tags>
</metadata>
</package>
\ No newline at end of file
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>NuGet.CommandLine</id>
<version>2.0.40001</version>
<authors>Outercurve Foundation</authors>
<owners>Outercurve Foundation</owners>
<licenseUrl>http://nuget.codeplex.com/license</licenseUrl>
<projectUrl>http://nuget.codeplex.com/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>NuGet Command Line Tool</description>
</metadata>
</package>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册