This commit is contained in:
sunkaixuan 2017-04-23 14:07:04 +08:00
parent 6de8c507ea
commit 3e4a7163c6
3 changed files with 99 additions and 32 deletions

View File

@ -38,7 +38,7 @@ namespace OrmTest.UnitTest
#region dr ot entity #region dr ot entity
db.IgnoreComumns.Add("TestId", "Student"); db.IgnoreComumns.Add("TestId", "Student");
var dr3 = db.Queryable<Student>().Select(it => new ViewModelStudent2 { Student = it }).ToList(); var dr3 = db.Queryable<Student>().Select(it => new ViewModelStudent2 { Name=it.Name,Student=it}).ToList();
var dr0 = db.Queryable<Student>().Select(it => new { id=it.Id,w=new { x=it } }).ToList(); var dr0 = db.Queryable<Student>().Select(it => new { id=it.Id,w=new { x=it } }).ToList();
var dr1 = db.Queryable<Student>().Select(it => new { newid = it.Id }).ToList(); var dr1 = db.Queryable<Student>().Select(it => new { newid = it.Id }).ToList();
var dr2 = db.Queryable<Student>().Select(it => new { newid = it.Id, obj = it }).ToList(); var dr2 = db.Queryable<Student>().Select(it => new { newid = it.Id, obj = it }).ToList();

View File

@ -18,7 +18,7 @@ namespace SqlSugar
} }
else else
{ {
eblist = IDataReaderEntityBuilder<T>.CreateBuilder(type, dataReader, context); eblist =new IDataReaderEntityBuilder<T>(context,dataReader).CreateBuilder(type);
cacheManager.Add(key, eblist); cacheManager.Add(key, eblist);
} }
List<T> list = new List<T>(); List<T> list = new List<T>();

View File

@ -9,6 +9,17 @@ namespace SqlSugar
{ {
public partial class IDataReaderEntityBuilder<T> public partial class IDataReaderEntityBuilder<T>
{ {
private SqlSugarClient Context = null;
private IDataReaderEntityBuilder<T> DynamicBuilder;
private IDataRecord DataRecord;
private IDataReaderEntityBuilder() {
}
public IDataReaderEntityBuilder(SqlSugarClient context, IDataRecord dataRecord) {
this.Context = context;
this.DataRecord = dataRecord;
this.DynamicBuilder=new IDataReaderEntityBuilder<T>();
}
#region fields #region fields
private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) }); private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) });
private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) }); private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) });
@ -38,7 +49,7 @@ namespace SqlSugar
private static readonly MethodInfo getConvertEnum_Null = typeof(IDataRecordExtensions).GetMethod("GetConvertEnum_Null"); private static readonly MethodInfo getConvertEnum_Null = typeof(IDataRecordExtensions).GetMethod("GetConvertEnum_Null");
private static readonly MethodInfo getOtherNull = typeof(IDataRecordExtensions).GetMethod("GetOtherNull"); private static readonly MethodInfo getOtherNull = typeof(IDataRecordExtensions).GetMethod("GetOtherNull");
private static readonly MethodInfo getOther = typeof(IDataRecordExtensions).GetMethod("GetOther"); private static readonly MethodInfo getOther = typeof(IDataRecordExtensions).GetMethod("GetOther");
private static readonly MethodInfo getEntity= typeof(IDataRecordExtensions).GetMethod("getEntity"); private static readonly MethodInfo getEntity = typeof(IDataRecordExtensions).GetMethod("getEntity");
private delegate T Load(IDataRecord dataRecord); private delegate T Load(IDataRecord dataRecord);
private Load handler; private Load handler;
#endregion #endregion
@ -49,55 +60,111 @@ namespace SqlSugar
return handler(dataRecord); return handler(dataRecord);
} }
public static IDataReaderEntityBuilder<T> CreateBuilder(Type type, IDataRecord dataRecord, SqlSugarClient context) public IDataReaderEntityBuilder<T> CreateBuilder(Type type)
{ {
IDataReaderEntityBuilder<T> dynamicBuilder = new IDataReaderEntityBuilder<T>();
DynamicMethod method = new DynamicMethod("DynamicCreateEntity", type, DynamicMethod method = new DynamicMethod("DynamicCreateEntity", type,
new Type[] { typeof(IDataRecord) }, type, true); new Type[] { typeof(IDataRecord) }, type, true);
ILGenerator generator = method.GetILGenerator(); ILGenerator generator = method.GetILGenerator();
LocalBuilder result = generator.DeclareLocal(type); LocalBuilder result = generator.DeclareLocal(type);
generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
generator.Emit(OpCodes.Stloc, result); generator.Emit(OpCodes.Stloc, result);
var mappingColumns = context.MappingColumns.Where(it => it.EntityName.Equals(type.Name,StringComparison.CurrentCultureIgnoreCase)).ToList(); var mappingColumns = Context.MappingColumns.Where(it => it.EntityName.Equals(type.Name, StringComparison.CurrentCultureIgnoreCase)).ToList();
for (int i = 0; i < dataRecord.FieldCount; i++) var properties = type.GetProperties();
foreach (var propertyInfo in properties)
{ {
string dbFieldName = dataRecord.GetName(i); string fileName = propertyInfo.Name;
string propName = dbFieldName; if (mappingColumns != null)
if (mappingColumns != null&& mappingColumns.Any())
{ {
var mappingInfo = mappingColumns.SingleOrDefault(it => it.DbColumnName.Equals(dbFieldName, StringComparison.CurrentCultureIgnoreCase)); var mappInfo = mappingColumns.SingleOrDefault(it => it.EntityName.Equals(propertyInfo.Name));
if (mappingInfo != null) if (mappInfo != null)
{ {
propName = mappingInfo.EntityPropertyName; fileName = mappInfo.DbColumnName;
} }
} }
PropertyInfo propertyInfo = type.GetProperty(type.GetProperties().Single(it=>it.Name.Equals(propName,StringComparison.CurrentCultureIgnoreCase)).Name); if (Context.IgnoreComumns != null && Context.IgnoreComumns.Any(it => it.EntityPropertyName.Equals(propertyInfo.Name, StringComparison.CurrentCultureIgnoreCase)
Label endIfLabel = generator.DefineLabel(); && it.EntityName.Equals(type.Name, StringComparison.CurrentCultureIgnoreCase)))
{
continue;
}
if (propertyInfo != null && propertyInfo.GetSetMethod() != null) if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
{ {
bool isNullable = false; if (propertyInfo.PropertyType.IsClass())
var underType = PubMethod.GetUnderType(propertyInfo, ref isNullable); {
generator.Emit(OpCodes.Ldarg_0); //BindClass(dataRecord, context, generator, result, propertyInfo,fileName);
generator.Emit(OpCodes.Ldc_I4, i); }
generator.Emit(OpCodes.Callvirt, isDBNullMethod); else
generator.Emit(OpCodes.Brtrue, endIfLabel); {
generator.Emit(OpCodes.Ldloc, result); BindField(generator, result, propertyInfo, fileName);
generator.Emit(OpCodes.Ldarg_0); }
generator.Emit(OpCodes.Ldc_I4, i);
GeneratorCallMethod(generator, underType, isNullable, propertyInfo, dataRecord.GetDataTypeName(i), propName, context);
generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
generator.MarkLabel(endIfLabel);
} }
} }
generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldloc, result);
generator.Emit(OpCodes.Ret); generator.Emit(OpCodes.Ret);
dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); DynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load));
return dynamicBuilder; return DynamicBuilder;
}
private void CreateBuilder_Part(ILGenerator generator, LocalBuilder result, PropertyInfo propertyInfo, List<MappingColumn> mappingColumns)
{
foreach (var prop in propertyInfo.PropertyType.GetProperties())
{
string entityName = propertyInfo.PropertyType.Name;
string entityProptertyName = prop.Name;
string fileName = entityName + "." + entityProptertyName;
if (Context.IgnoreComumns != null && Context.IgnoreComumns.Any(it => it.EntityPropertyName.Equals(entityProptertyName, StringComparison.CurrentCultureIgnoreCase)
&& it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)))
{
continue;
}
if (mappingColumns != null)
{
var mappInfo = mappingColumns.SingleOrDefault(it => it.EntityName.Equals(propertyInfo.Name));
if (mappInfo != null)
{
fileName = mappInfo.DbColumnName;
}
}
BindField(generator, result, prop, fileName);
}
}
private void BindClass(ILGenerator generator, LocalBuilder result, PropertyInfo propertyInfo, string fileName)
{
int i = DataRecord.GetOrdinal(fileName);
bool isNullable = false;
Label endIfLabel = generator.DefineLabel();
var underType = PubMethod.GetUnderType(propertyInfo, ref isNullable);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Callvirt, isDBNullMethod);
generator.Emit(OpCodes.Brtrue, endIfLabel);
generator.Emit(OpCodes.Ldloc, result);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
generator.MarkLabel(endIfLabel);
}
private void BindField( ILGenerator generator, LocalBuilder result, PropertyInfo propertyInfo, string fileName)
{
int i = DataRecord.GetOrdinal(fileName);
bool isNullable = false;
Label endIfLabel = generator.DefineLabel();
var underType = PubMethod.GetUnderType(propertyInfo, ref isNullable);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Callvirt, isDBNullMethod);
generator.Emit(OpCodes.Brtrue, endIfLabel);
generator.Emit(OpCodes.Ldloc, result);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, i);
GeneratorCallMethod(generator, underType, isNullable, propertyInfo, DataRecord.GetDataTypeName(i), propertyInfo.Name);
generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
generator.MarkLabel(endIfLabel);
} }
#endregion #endregion
#region helpers #region helpers
private static void CheckType(List<string> errorTypes, string objType, string dbType, string field) private void CheckType(List<string> errorTypes, string objType, string dbType, string field)
{ {
var isAny = errorTypes.Contains(objType); var isAny = errorTypes.Contains(objType);
if (isAny) if (isAny)
@ -106,9 +173,9 @@ namespace SqlSugar
} }
} }
private static void GeneratorCallMethod(ILGenerator generator, Type type, bool isNullable, PropertyInfo pro, string dbTypeName, string fieldName, SqlSugarClient context) private void GeneratorCallMethod(ILGenerator generator, Type type, bool isNullable, PropertyInfo pro, string dbTypeName, string fieldName)
{ {
var bind = context.Database.DbBind; var bind = Context.Database.DbBind;
List<string> guidThrow = bind.GuidThrow; List<string> guidThrow = bind.GuidThrow;
List<string> intThrow = bind.IntThrow; List<string> intThrow = bind.IntThrow;
List<string> stringThrow = bind.StringThrow; List<string> stringThrow = bind.StringThrow;