fixed bug in tests, added support for non-tracked concrete class in Get(),...

fixed bug in tests, added support for non-tracked concrete class in Get(), emitting a concrete class which seems stupid, but works (due to the generic get method returning both interface and new class)
parent f38d1103
...@@ -39,22 +39,6 @@ private IDbConnection GetOpenConnection() ...@@ -39,22 +39,6 @@ private IDbConnection GetOpenConnection()
return connection; return connection;
} }
public void Get()
{
using (var connection = GetOpenConnection())
{
try
{
connection.Get<User>(1);
Debug.Fail("Fail, should have thrown exception");
}
catch (Exception)
{
}
}
}
public void InsertGetUpdate() public void InsertGetUpdate()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
...@@ -63,6 +47,8 @@ public void InsertGetUpdate() ...@@ -63,6 +47,8 @@ public void InsertGetUpdate()
var id = connection.Insert(new User {Name = "Adam", Age = 10}); var id = connection.Insert(new User {Name = "Adam", Age = 10});
id.IsEqualTo(1); id.IsEqualTo(1);
//get a user with "isdirty" tracking
var user = connection.Get<IUser>(id); var user = connection.Get<IUser>(id);
user.Name.IsEqualTo("Adam"); user.Name.IsEqualTo("Adam");
connection.Update(user).IsEqualTo(false); //returns false if not updated, based on tracking connection.Update(user).IsEqualTo(false); //returns false if not updated, based on tracking
...@@ -70,9 +56,20 @@ public void InsertGetUpdate() ...@@ -70,9 +56,20 @@ public void InsertGetUpdate()
connection.Update(user).IsEqualTo(true); //returns true if updated, based on tracking connection.Update(user).IsEqualTo(true); //returns true if updated, based on tracking
user = connection.Get<IUser>(id); user = connection.Get<IUser>(id);
user.Name.IsEqualTo("Bob"); user.Name.IsEqualTo("Bob");
connection.Query<User>("select * from Users").Count().Equals(2);
connection.Delete(user).Equals(true); //get a user with no tracking
connection.Query<User>("select * from Users").Count().Equals(1); var notrackedUser = connection.Get<User>(1);
notrackedUser.Name.IsEqualTo("Bob");
connection.Update(notrackedUser).IsEqualTo(true); //returns true, even though user was not changed
notrackedUser.Name = "Cecil";
connection.Update(notrackedUser).IsEqualTo(true);
connection.Get<User>(1).Name.IsEqualTo("Cecil");
connection.Query<User>("select * from Users").Count().IsEqualTo(1);
connection.Delete(user).IsEqualTo(true);
connection.Query<User>("select * from Users").Count().IsEqualTo(0);
connection.Update(notrackedUser).IsEqualTo(false); //returns false, user not found
} }
} }
} }
......
...@@ -27,6 +27,29 @@ private static AssemblyBuilder GetAsmBuilder(string name) ...@@ -27,6 +27,29 @@ private static AssemblyBuilder GetAsmBuilder(string name)
return assemblyBuilder; return assemblyBuilder;
} }
public static T GetClassProxy<T>()
{
Type typeOfT = typeof(T);
if (TypeCache.ContainsKey(typeOfT))
{
return (T)TypeCache[typeOfT];
}
var assemblyBuilder = GetAsmBuilder(typeOfT.Name);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("SqlMapperExtensions." + typeOfT.Name); //NOTE: to save, add "asdasd.dll" parameter
var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "_" + Guid.NewGuid(),
TypeAttributes.Public | TypeAttributes.Class, typeOfT);
var generatedType = typeBuilder.CreateType();
var generatedObject = Activator.CreateInstance(generatedType);
TypeCache.Add(typeOfT, generatedObject);
return (T)generatedObject;
}
public static T GetInterfaceProxy<T>() public static T GetInterfaceProxy<T>()
{ {
Type typeOfT = typeof(T); Type typeOfT = typeof(T);
...@@ -40,7 +63,6 @@ public static T GetInterfaceProxy<T>() ...@@ -40,7 +63,6 @@ public static T GetInterfaceProxy<T>()
var moduleBuilder = assemblyBuilder.DefineDynamicModule("SqlMapperExtensions." + typeOfT.Name); //NOTE: to save, add "asdasd.dll" parameter var moduleBuilder = assemblyBuilder.DefineDynamicModule("SqlMapperExtensions." + typeOfT.Name); //NOTE: to save, add "asdasd.dll" parameter
var interfaceType = typeof(IProxy); var interfaceType = typeof(IProxy);
var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "_" + Guid.NewGuid(), var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "_" + Guid.NewGuid(),
TypeAttributes.Public | TypeAttributes.Class); TypeAttributes.Public | TypeAttributes.Class);
typeBuilder.AddInterfaceImplementation(typeOfT); typeBuilder.AddInterfaceImplementation(typeOfT);
......
...@@ -49,11 +49,12 @@ private static IEnumerable<PropertyInfo> TypePropertiesCache(Type type) ...@@ -49,11 +49,12 @@ private static IEnumerable<PropertyInfo> TypePropertiesCache(Type type)
/// <param name="connection">Open SqlConnection</param> /// <param name="connection">Open SqlConnection</param>
/// <param name="id">Id of the entity to get, must be marked with [Key] attribute</param> /// <param name="id">Id of the entity to get, must be marked with [Key] attribute</param>
/// <returns>Entity of T</returns> /// <returns>Entity of T</returns>
public static T Get<T>(this IDbConnection connection, object id) public static T Get<T>(this IDbConnection connection, object id)
{ {
var type = typeof(T); var type = typeof(T);
if (!type.IsInterface)
throw new DataException("This version of Get<T>() only supports interfaces."); // if (!type.IsInterface)
// throw new DataException("This version of Get<T>() only supports interfaces.");
var keys = KeyPropertiesCache(type); var keys = KeyPropertiesCache(type);
if (keys.Count() > 1) if (keys.Count() > 1)
...@@ -72,15 +73,17 @@ public static T Get<T>(this IDbConnection connection, object id) ...@@ -72,15 +73,17 @@ public static T Get<T>(this IDbConnection connection, object id)
if (res == null) if (res == null)
return (T) ((object) null); return (T) ((object) null);
var obj = type.IsInterface ? ProxyGenerator.GetInterfaceProxy<T>() : ProxyGenerator.GetClassProxy<T>();
var proxy = ProxyGenerator.GetInterfaceProxy<T>();
foreach (var property in TypePropertiesCache(type)) foreach (var property in TypePropertiesCache(type))
{ {
var val = res.GetProperty(property.Name); var val = res.GetProperty(property.Name);
property.SetValue(proxy, val, null); property.SetValue(obj, val, null);
} }
((IProxy)proxy).IsDirty = false; //reset change tracking and return if(type.IsInterface)
return proxy; ((IProxy)obj).IsDirty = false; //reset change tracking and return
return obj;
} }
...@@ -136,7 +139,7 @@ public static long Insert<T>(this IDbConnection connection, T entityToInsert) ...@@ -136,7 +139,7 @@ public static long Insert<T>(this IDbConnection connection, T entityToInsert)
/// <returns>true if updated, false if not found or not modified (tracked entities)</returns> /// <returns>true if updated, false if not found or not modified (tracked entities)</returns>
public static bool Update<T>(this IDbConnection connection, T entityToUpdate) public static bool Update<T>(this IDbConnection connection, T entityToUpdate)
{ {
var proxy = ((IProxy)entityToUpdate); var proxy = entityToUpdate as IProxy;
if (proxy != null) if (proxy != null)
{ {
if (!proxy.IsDirty) return false; if (!proxy.IsDirty) return false;
......
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