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

Provide support for OleDB / anonymous sql parameters

上级 8f017a25
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NuGet.CommandLine" version="2.0.40001" />
<package id="NuGet.CommandLine" version="2.5.0" /> <package id="NuGet.CommandLine" version="2.5.0" />
<package id="NuGet.CommandLine" version="2.0.40001" />
</packages> </packages>
\ No newline at end of file
...@@ -683,7 +683,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, string sql, objec ...@@ -683,7 +683,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, string sql, objec
/// <returns>Number of rows affected</returns> /// <returns>Number of rows affected</returns>
public static int Execute( public static int Execute(
#if CSHARP30 #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 #else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif #endif
...@@ -741,35 +741,40 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn ...@@ -741,35 +741,40 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
/// <summary> /// <summary>
/// Return a list of dynamic objects, reader is closed after the call /// Return a list of dynamic objects, reader is closed after the call
/// </summary> /// </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); return Query(cnn, sql, param, null, true, null, null);
} }
/// <summary> /// <summary>
/// Return a list of dynamic objects, reader is closed after the call /// Return a list of dynamic objects, reader is closed after the call
/// </summary> /// </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); return Query(cnn, sql, param, transaction, true, null, null);
} }
/// <summary> /// <summary>
/// Return a list of dynamic objects, reader is closed after the call /// Return a list of dynamic objects, reader is closed after the call
/// </summary> /// </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); return Query(cnn, sql, param, null, true, null, commandType);
} }
/// <summary> /// <summary>
/// Return a list of dynamic objects, reader is closed after the call /// Return a list of dynamic objects, reader is closed after the call
/// </summary> /// </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); return Query(cnn, sql, param, transaction, true, null, commandType);
} }
/// <summary> /// <summary>
/// Return a list of dynamic objects, reader is closed after the call /// Return a list of dynamic objects, reader is closed after the call
/// </summary> /// </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); return Query<IDictionary<string, object>>(cnn, sql, param, transaction, buffered, commandTimeout, commandType);
} }
#endif #endif
...@@ -783,7 +788,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn ...@@ -783,7 +788,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
/// </returns> /// </returns>
public static IEnumerable<T> Query<T>( public static IEnumerable<T> Query<T>(
#if CSHARP30 #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 #else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null
#endif #endif
...@@ -798,7 +803,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn ...@@ -798,7 +803,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
/// </summary> /// </summary>
public static GridReader QueryMultiple( public static GridReader QueryMultiple(
#if CSHARP30 #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 #else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif #endif
...@@ -909,7 +914,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -909,7 +914,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <returns></returns> /// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>( public static IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>(
#if CSHARP30 #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 #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 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 #endif
...@@ -937,7 +942,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -937,7 +942,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <returns></returns> /// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>( public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(
#if CSHARP30 #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 #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 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 #endif
...@@ -966,7 +971,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -966,7 +971,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <returns></returns> /// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TReturn>( public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TReturn>(
#if CSHARP30 #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 #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 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 #endif
...@@ -1247,7 +1252,7 @@ private static CacheInfo GetCacheInfo(Identity identity) ...@@ -1247,7 +1252,7 @@ private static CacheInfo GetCacheInfo(Identity identity)
#endif #endif
else else
{ {
info.ParamReader = CreateParamInfoGenerator(identity, false); info.ParamReader = CreateParamInfoGenerator(identity, false, true);
} }
} }
SetQueryCache(identity, info); SetQueryCache(identity, info);
...@@ -1265,7 +1270,7 @@ private static CacheInfo GetCacheInfo(Identity identity) ...@@ -1265,7 +1270,7 @@ private static CacheInfo GetCacheInfo(Identity identity)
return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing); return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing);
} }
#else #else
if(type.IsAssignableFrom(typeof(Dictionary<string,object>))) if (type.IsAssignableFrom(typeof(Dictionary<string, object>)))
{ {
return GetDictionaryDeserializer(reader, startBound, length, returnNullIfFirstMissing); return GetDictionaryDeserializer(reader, startBound, length, returnNullIfFirstMissing);
} }
...@@ -1831,13 +1836,22 @@ private static IEnumerable<PropertyInfo> FilterParameters(IEnumerable<PropertyIn ...@@ -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)); 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> /// <summary>
/// Internal use only /// Internal use only
/// </summary> /// </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; 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 dm = new DynamicMethod(string.Format("ParamInfo{0}", Guid.NewGuid()), null, new[] { typeof(IDbCommand), typeof(object) }, type, true);
var il = dm.GetILGenerator(); var il = dm.GetILGenerator();
...@@ -1851,11 +1865,63 @@ private static IEnumerable<PropertyInfo> FilterParameters(IEnumerable<PropertyIn ...@@ -1851,11 +1865,63 @@ private static IEnumerable<PropertyInfo> FilterParameters(IEnumerable<PropertyIn
il.Emit(OpCodes.Ldarg_0); // stack is now [command] il.Emit(OpCodes.Ldarg_0); // stack is now [command]
il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty("Parameters").GetGetMethod(), null); // stack is now [parameters] 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) if (filterParams)
{ {
props = FilterParameters(props, identity.sql); props = FilterParameters(props, identity.sql);
} }
foreach (var prop in props) foreach (var prop in props)
{ {
if (filterParams) if (filterParams)
...@@ -2154,7 +2220,7 @@ public static void SetTypeMap(Type type, ITypeMap map) ...@@ -2154,7 +2220,7 @@ public static void SetTypeMap(Type type, ITypeMap map)
/// <returns></returns> /// <returns></returns>
public static Func<IDataReader, object> GetTypeDeserializer( public static Func<IDataReader, object> GetTypeDeserializer(
#if CSHARP30 #if CSHARP30
Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing
#else #else
Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false
#endif #endif
...@@ -2896,7 +2962,10 @@ partial class ParamInfo ...@@ -2896,7 +2962,10 @@ partial class ParamInfo
/// <summary> /// <summary>
/// construct a dynamic parameter bag /// construct a dynamic parameter bag
/// </summary> /// </summary>
public DynamicParameters() { } public DynamicParameters()
{
RemoveUnused = true;
}
/// <summary> /// <summary>
/// construct a dynamic parameter bag /// construct a dynamic parameter bag
...@@ -2904,6 +2973,7 @@ partial class ParamInfo ...@@ -2904,6 +2973,7 @@ partial class ParamInfo
/// <param name="template">can be an anonymous type or a DynamicParameters bag</param> /// <param name="template">can be an anonymous type or a DynamicParameters bag</param>
public DynamicParameters(object template) public DynamicParameters(object template)
{ {
RemoveUnused = true;
AddDynamicParams(template); AddDynamicParams(template);
} }
...@@ -2914,7 +2984,7 @@ public DynamicParameters(object template) ...@@ -2914,7 +2984,7 @@ public DynamicParameters(object template)
/// <param name="param"></param> /// <param name="param"></param>
public void AddDynamicParams( public void AddDynamicParams(
#if CSHARP30 #if CSHARP30
object param object param
#else #else
dynamic param dynamic param
#endif #endif
...@@ -2976,7 +3046,7 @@ dynamic param ...@@ -2976,7 +3046,7 @@ dynamic param
/// <param name="size"></param> /// <param name="size"></param>
public void Add( public void Add(
#if CSHARP30 #if CSHARP30
string name, object value, DbType? dbType, ParameterDirection? direction, int? size string name, object value, DbType? dbType, ParameterDirection? direction, int? size
#else #else
string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null
#endif #endif
...@@ -3005,6 +3075,11 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Id ...@@ -3005,6 +3075,11 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Id
AddParameters(command, identity); 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> /// <summary>
/// Add all the parameters needed to the command just before it executes /// Add all the parameters needed to the command just before it executes
/// </summary> /// </summary>
...@@ -3023,7 +3098,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity) ...@@ -3023,7 +3098,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{ {
if (!paramReaderCache.TryGetValue(newIdent, out appender)) if (!paramReaderCache.TryGetValue(newIdent, out appender))
{ {
appender = SqlMapper.CreateParamInfoGenerator(newIdent, true); appender = SqlMapper.CreateParamInfoGenerator(newIdent, true, RemoveUnused);
paramReaderCache[newIdent] = appender; paramReaderCache[newIdent] = appender;
} }
} }
......
...@@ -78,7 +78,7 @@ internal class SomaConfig : Soma.Core.MsSqlConfig ...@@ -78,7 +78,7 @@ internal class SomaConfig : Soma.Core.MsSqlConfig
{ {
public override string ConnectionString public override string ConnectionString
{ {
get { return Program.connectionString; } get { return Program.ConnectionString; }
} }
public override void Log(Soma.Core.PreparedStatement preparedStatement) public override void Log(Soma.Core.PreparedStatement preparedStatement)
...@@ -134,17 +134,17 @@ public void Run(int iterations) ...@@ -134,17 +134,17 @@ public void Run(int iterations)
var mapperConnection3 = Program.GetOpenConnection(); var mapperConnection3 = Program.GetOpenConnection();
tests.Add(id => mapperConnection2.Get<Post>(id), "Dapper.Cotrib"); 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(); var massiveConnection = Program.GetOpenConnection();
tests.Add(id => massiveModel.Query("select * from Posts where Id = @0", massiveConnection, id).First(), "Dynamic Massive ORM Query"); tests.Add(id => massiveModel.Query("select * from Posts where Id = @0", massiveConnection, id).First(), "Dynamic Massive ORM Query");
// PetaPoco test with all default options // 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(); petapoco.OpenSharedConnection();
tests.Add(id => petapoco.Fetch<Post>("SELECT * from Posts where Id=@0", id), "PetaPoco (Normal)"); tests.Add(id => petapoco.Fetch<Post>("SELECT * from Posts where Id=@0", id), "PetaPoco (Normal)");
// PetaPoco with some "smart" functionality disabled // 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.OpenSharedConnection();
petapocoFast.EnableAutoSelect = false; petapocoFast.EnableAutoSelect = false;
petapocoFast.EnableNamedParams = false; petapocoFast.EnableNamedParams = false;
...@@ -188,7 +188,7 @@ public void Run(int iterations) ...@@ -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"); tests.Add(id => db1.SetCommand("select * from Posts where Id = @id", db1.Parameter("id", id)).ExecuteList<Post>(), "BLToolkit");
// Simple.Data // 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"); tests.Add(id => sdb.Posts.FindById(id), "Simple.Data");
// Soma // Soma
......
...@@ -28,11 +28,12 @@ class Post ...@@ -28,11 +28,12 @@ class Post
class Program 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() public static SqlConnection GetOpenConnection()
{ {
var connection = new SqlConnection(connectionString); var connection = new SqlConnection(ConnectionString);
connection.Open(); connection.Open();
return connection; return connection;
} }
......
...@@ -79,10 +79,12 @@ public void TestMultiMapWithConstructor() ...@@ -79,10 +79,12 @@ public void TestMultiMapWithConstructor()
insert #Posts values(2, 99, 'Sams Post2') insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')"; insert #Posts values(3, null, 'no ones post')";
connection.Execute(createSql); connection.Execute(createSql);
try
{
string sql = @"select * from #Posts p string sql = @"select * from #Posts p
left join #Users u on u.Id = p.OwnerId left join #Users u on u.Id = p.OwnerId
Order by p.Id"; 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(); var p = data.First();
p.FullContent.IsEqualTo("Sams Post1"); p.FullContent.IsEqualTo("Sams Post1");
...@@ -91,9 +93,12 @@ public void TestMultiMapWithConstructor() ...@@ -91,9 +93,12 @@ public void TestMultiMapWithConstructor()
p.Owner.Ident.IsEqualTo(99); p.Owner.Ident.IsEqualTo(99);
data[2].Owner.IsNull(); data[2].Owner.IsNull();
}
finally
{
connection.Execute("drop table #Users drop table #Posts"); connection.Execute("drop table #Users drop table #Posts");
} }
}
class MultipleConstructors class MultipleConstructors
...@@ -159,7 +164,7 @@ public NoDefaultConstructor(int a1, int? b1, float f1, string s1, Guid G1) ...@@ -159,7 +164,7 @@ public NoDefaultConstructor(int a1, int? b1, float f1, string s1, Guid G1)
public void TestNoDefaultConstructor() public void TestNoDefaultConstructor()
{ {
var guid = Guid.NewGuid(); 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.A.IsEqualTo(0);
nodef.B.IsEqualTo(null); nodef.B.IsEqualTo(null);
nodef.F.IsEqualTo(0); nodef.F.IsEqualTo(0);
...@@ -315,6 +320,8 @@ public void PassInEmptyIntArray() ...@@ -315,6 +320,8 @@ public void PassInEmptyIntArray()
public void TestSchemaChanged() public void TestSchemaChanged()
{ {
connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')"); 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(); var d = connection.Query<Dog>("select * from #dog").Single();
d.Name.IsEqualTo("Alf"); d.Name.IsEqualTo("Alf");
d.Age.IsEqualTo(1); d.Age.IsEqualTo(1);
...@@ -322,12 +329,18 @@ public void TestSchemaChanged() ...@@ -322,12 +329,18 @@ public void TestSchemaChanged()
d = connection.Query<Dog>("select * from #dog").Single(); d = connection.Query<Dog>("select * from #dog").Single();
d.Name.IsNull(); d.Name.IsNull();
d.Age.IsEqualTo(1); d.Age.IsEqualTo(1);
}
finally
{
connection.Execute("drop table #dog"); connection.Execute("drop table #dog");
} }
}
public void TestSchemaChangedMultiMap() public void TestSchemaChangedMultiMap()
{ {
connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')"); 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(); 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"); tuple.Item1.Name.IsEqualTo("Alf");
...@@ -342,9 +355,12 @@ public void TestSchemaChangedMultiMap() ...@@ -342,9 +355,12 @@ public void TestSchemaChangedMultiMap()
tuple.Item1.Age.IsEqualTo(1); tuple.Item1.Age.IsEqualTo(1);
tuple.Item2.Name.IsNull(); tuple.Item2.Name.IsNull();
tuple.Item2.Age.IsEqualTo(1); tuple.Item2.Age.IsEqualTo(1);
}
finally
{
connection.Execute("drop table #dog"); connection.Execute("drop table #dog");
} }
}
public void TestReadMultipleIntegersWithSplitOnAny() public void TestReadMultipleIntegersWithSplitOnAny()
{ {
...@@ -404,7 +420,7 @@ public void CheckComplexConcat() ...@@ -404,7 +420,7 @@ public void CheckComplexConcat()
string term = "F"; // the term the user searched for string term = "F"; // the term the user searched for
connection.Execute(@"create table #users16726709 (first_name varchar(200), last_name varchar(200)) 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 // Using Dapper
connection.Query(end_wildcard, new { search_term = term }).Count().IsEqualTo(2); connection.Query(end_wildcard, new { search_term = term }).Count().IsEqualTo(2);
...@@ -462,7 +478,7 @@ public class Dog ...@@ -462,7 +478,7 @@ public class Dog
public void TestExtraFields() public void TestExtraFields()
{ {
var guid = Guid.NewGuid(); 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() dog.Count()
.IsEqualTo(1); .IsEqualTo(1);
...@@ -474,6 +490,20 @@ public void TestExtraFields() ...@@ -474,6 +490,20 @@ public void TestExtraFields()
.IsEqualTo(guid); .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() public void TestStrongType()
{ {
...@@ -542,11 +572,18 @@ public void TestExecuteCommandWithHybridParameters() ...@@ -542,11 +572,18 @@ public void TestExecuteCommandWithHybridParameters()
public void TestExecuteMultipleCommand() public void TestExecuteMultipleCommand()
{ {
connection.Execute("create table #t(i int)"); 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 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); tally.IsEqualTo(4);
sum.IsEqualTo(10); sum.IsEqualTo(10);
} }
finally
{
connection.Execute("drop table #t");
}
}
class Student class Student
{ {
...@@ -557,15 +594,22 @@ class Student ...@@ -557,15 +594,22 @@ class Student
public void TestExecuteMultipleCommandStrongType() public void TestExecuteMultipleCommandStrongType()
{ {
connection.Execute("create table #t(Name nvarchar(max), Age int)"); 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> int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student>
{ {
new Student{Age = 1, Name = "sam"}, new Student{Age = 1, Name = "sam"},
new Student{Age = 2, Name = "bob"} 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); tally.IsEqualTo(2);
sum.IsEqualTo(3); sum.IsEqualTo(3);
} }
finally
{
connection.Execute("drop table #t");
}
}
public void TestExecuteMultipleCommandObjectArray() public void TestExecuteMultipleCommandObjectArray()
{ {
...@@ -591,7 +635,7 @@ class TestObj ...@@ -591,7 +635,7 @@ class TestObj
public int _priv; public int _priv;
private int Priv { set { _priv = value; } } private int Priv { set { _priv = value; } }
private int PrivGet { get { return _priv;} } private int PrivGet { get { return _priv; } }
} }
public void TestSetInternal() public void TestSetInternal()
...@@ -712,9 +756,10 @@ public void TestMultiMap() ...@@ -712,9 +756,10 @@ public void TestMultiMap()
insert #Posts values(3, null, 'no ones post') insert #Posts values(3, null, 'no ones post')
"; ";
connection.Execute(createSql); connection.Execute(createSql);
try
{
var sql = var sql =
@"select * from #Posts p @"select * from #Posts p
left join #Users u on u.Id = p.OwnerId left join #Users u on u.Id = p.OwnerId
Order by p.Id"; Order by p.Id";
...@@ -727,9 +772,12 @@ public void TestMultiMap() ...@@ -727,9 +772,12 @@ public void TestMultiMap()
p.Owner.Id.IsEqualTo(99); p.Owner.Id.IsEqualTo(99);
data[2].Owner.IsNull(); data[2].Owner.IsNull();
}
finally
{
connection.Execute("drop table #Users drop table #Posts"); connection.Execute("drop table #Users drop table #Posts");
} }
}
...@@ -1592,12 +1640,13 @@ public void TestMultiMapThreeTypesWithGridReader() ...@@ -1592,12 +1640,13 @@ public void TestMultiMapThreeTypesWithGridReader()
insert #Comments values(1, 1, 'Comment 1')"; insert #Comments values(1, 1, 'Comment 1')";
connection.Execute(createSql); connection.Execute(createSql);
try
{
var sql = @"SELECT p.* FROM #Posts p var sql = @"SELECT p.* FROM #Posts p
select p.*, u.Id, u.Name + '0' Name, c.Id, c.CommentData 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 #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 where p.Id = 1
Order by p.Id"; Order by p.Id";
...@@ -1610,9 +1659,12 @@ public void TestMultiMapThreeTypesWithGridReader() ...@@ -1610,9 +1659,12 @@ public void TestMultiMapThreeTypesWithGridReader()
post2.Comment.Id.IsEqualTo(1); post2.Comment.Id.IsEqualTo(1);
post2.Owner.Id.IsEqualTo(99); post2.Owner.Id.IsEqualTo(99);
}
finally
{
connection.Execute("drop table #Users drop table #Posts drop table #Comments"); connection.Execute("drop table #Users drop table #Posts drop table #Comments");
} }
}
public class DbParams : Dapper.SqlMapper.IDynamicParameters, IEnumerable<IDbDataParameter> public class DbParams : Dapper.SqlMapper.IDynamicParameters, IEnumerable<IDbDataParameter>
{ {
...@@ -1656,7 +1708,8 @@ public void TestReadDynamicWithGridReader() ...@@ -1656,7 +1708,8 @@ public void TestReadDynamicWithGridReader()
insert #Posts values(1, 99, 'Sams Post1') insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2') insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')"; insert #Posts values(3, null, 'no ones post')";
try
{
connection.Execute(createSql); connection.Execute(createSql);
var sql = @"SELECT * FROM #Users ORDER BY Id var sql = @"SELECT * FROM #Users ORDER BY Id
...@@ -1672,9 +1725,12 @@ public void TestReadDynamicWithGridReader() ...@@ -1672,9 +1725,12 @@ public void TestReadDynamicWithGridReader()
((int)users.First().Id).IsEqualTo(2); ((int)users.First().Id).IsEqualTo(2);
((int)posts.First().Id).IsEqualTo(3); ((int)posts.First().Id).IsEqualTo(3);
}
finally
{
connection.Execute("drop table #Users drop table #Posts"); connection.Execute("drop table #Users drop table #Posts");
} }
}
public void TestDynamicParamNullSupport() public void TestDynamicParamNullSupport()
{ {
...@@ -2081,7 +2137,8 @@ public void TestReaderWhenResultsChange() ...@@ -2081,7 +2137,8 @@ public void TestReaderWhenResultsChange()
obj4.X.IsEqualTo(1); obj4.X.IsEqualTo(1);
obj4.Y.IsEqualTo(1); obj4.Y.IsEqualTo(1);
obj4.Z.IsEqualTo(2); obj4.Z.IsEqualTo(2);
} finally }
finally
{ {
connection.Execute("drop table #ResultsChange;drop table #ResultsChange2;"); connection.Execute("drop table #ResultsChange;drop table #ResultsChange2;");
} }
...@@ -2324,11 +2381,13 @@ public void TestMultiSelectWithSomeEmptyGrids() ...@@ -2324,11 +2381,13 @@ public void TestMultiSelectWithSomeEmptyGrids()
var two = reader.Read<int>().ToArray(); var two = reader.Read<int>().ToArray();
var three = reader.Read<int>().ToArray(); var three = reader.Read<int>().ToArray();
var four = 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>(); reader.Read<int>();
throw new InvalidOperationException("this should not have worked!"); 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'."); 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() ...@@ -2345,7 +2404,7 @@ public void TestDynamicMutation()
{ {
var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single(); var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single();
((int)obj.a).IsEqualTo(1); ((int)obj.a).IsEqualTo(1);
IDictionary<string,object> dict = obj; IDictionary<string, object> dict = obj;
Assert.Equals(3, dict.Count); Assert.Equals(3, dict.Count);
Assert.IsTrue(dict.Remove("a")); Assert.IsTrue(dict.Remove("a"));
Assert.IsFalse(dict.Remove("d")); Assert.IsFalse(dict.Remove("d"));
...@@ -2524,7 +2583,7 @@ public void TestIssue17648290() ...@@ -2524,7 +2583,7 @@ public void TestIssue17648290()
var p = new DynamicParameters(); var p = new DynamicParameters();
int code = 1, getMessageControlId = 2; int code = 1, getMessageControlId = 2;
p.Add("@Code", code); p.Add("@Code", code);
p.Add("@MessageControlId", getMessageControlId); p.Add("@MessageControlID", getMessageControlId);
p.Add("@SuccessCode", dbType: DbType.Int32, direction: ParameterDirection.Output); p.Add("@SuccessCode", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@ErrorDescription", dbType: DbType.String, direction: ParameterDirection.Output, size: 255); p.Add("@ErrorDescription", dbType: DbType.String, direction: ParameterDirection.Output, size: 255);
connection.Execute(@"CREATE PROCEDURE #up_MessageProcessed_get 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.
先完成此消息的编辑!
想要评论请 注册