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()
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()
{
using (var connection = GetOpenConnection())
......@@ -63,6 +47,8 @@ public void InsertGetUpdate()
var id = connection.Insert(new User {Name = "Adam", Age = 10});
id.IsEqualTo(1);
//get a user with "isdirty" tracking
var user = connection.Get<IUser>(id);
user.Name.IsEqualTo("Adam");
connection.Update(user).IsEqualTo(false); //returns false if not updated, based on tracking
......@@ -70,9 +56,20 @@ public void InsertGetUpdate()
connection.Update(user).IsEqualTo(true); //returns true if updated, based on tracking
user = connection.Get<IUser>(id);
user.Name.IsEqualTo("Bob");
connection.Query<User>("select * from Users").Count().Equals(2);
connection.Delete(user).Equals(true);
connection.Query<User>("select * from Users").Count().Equals(1);
//get a user with no tracking
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)
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>()
{
Type typeOfT = typeof(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 interfaceType = typeof(IProxy);
var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "_" + Guid.NewGuid(),
TypeAttributes.Public | TypeAttributes.Class);
typeBuilder.AddInterfaceImplementation(typeOfT);
......
......@@ -49,11 +49,12 @@ private static IEnumerable<PropertyInfo> TypePropertiesCache(Type type)
/// <param name="connection">Open SqlConnection</param>
/// <param name="id">Id of the entity to get, must be marked with [Key] attribute</param>
/// <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);
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);
if (keys.Count() > 1)
......@@ -72,15 +73,17 @@ public static T Get<T>(this IDbConnection connection, object id)
if (res == 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))
{
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
return proxy;
if(type.IsInterface)
((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)
/// <returns>true if updated, false if not found or not modified (tracked entities)</returns>
public static bool Update<T>(this IDbConnection connection, T entityToUpdate)
{
var proxy = ((IProxy)entityToUpdate);
var proxy = entityToUpdate as IProxy;
if (proxy != null)
{
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