EF使用动态类型
2017-08-08 16:56
375 查看
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Data.Entity; usingSystem.Collections; usingSystem.Reflection.Emit; usingSystem.Reflection; namespaceDemo { publicclassProgram { publicstaticvoidMain(string[]args) { stringconnectionString= "Server=(local);IntegratedSecurity=true;Database=master"; using(DbContextcontext=newDbContext(connectionString)) { TypeBuilderbuilder=Program.CreateTypeBuilder( "MyDynamicAssembly","MyModule","MyType"); Program.CreateAutoImplementedProperty(builder,"name",typeof(string)); Program.CreateAutoImplementedProperty(builder,"type",typeof(string)); Program.CreateAutoImplementedProperty(builder,"id",typeof(int)); TyperesultType=builder.CreateType(); dynamicqueryResult=context.Database.SqlQuery( resultType,"SELECT*FROMsys.sysobjects"); Console.WriteLine("{0,20}{1,4}{2,10}","Name","Type","ID"); foreach(dynamiciteminqueryResult) { Console.WriteLine("{0,10}{1,4}{2,10}",item.name,item.type,item.id); } } Console.ReadKey(); } publicstaticTypeBuilderCreateTypeBuilder( stringassemblyName,stringmoduleName,stringtypeName) { TypeBuildertypeBuilder=AppDomain .CurrentDomain .DefineDynamicAssembly(newAssemblyName(assemblyName), AssemblyBuilderAccess.Run) .DefineDynamicModule(moduleName) .DefineType(typeName,TypeAttributes.Public); typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); returntypeBuilder; } publicstaticvoidCreateAutoImplementedProperty( TypeBuilderbuilder,stringpropertyName,TypepropertyType) { conststringPrivateFieldPrefix="m_"; conststringGetterPrefix="get_"; conststringSetterPrefix="set_"; //Generatethefield. FieldBuilderfieldBuilder=builder.DefineField( string.Concat(PrivateFieldPrefix,propertyName), propertyType,FieldAttributes.Private); //Generatetheproperty PropertyBuilderpropertyBuilder=builder.DefineProperty( propertyName,PropertyAttributes.HasDefault,propertyType,null); //Propertygetterandsetterattributes. MethodAttributespropertyMethodAttributes= MethodAttributes.Public|MethodAttributes.SpecialName| MethodAttributes.HideBySig; //Definethegettermethod. MethodBuildergetterMethod=builder.DefineMethod( string.Concat(GetterPrefix,propertyName), propertyMethodAttributes,propertyType,Type.EmptyTypes); //EmittheILcode. //ldarg.0 //ldfld,_field //ret ILGeneratorgetterILCode=getterMethod.GetILGenerator(); getterILCode.Emit(OpCodes.Ldarg_0); getterILCode.Emit(OpCodes.Ldfld,fieldBuilder); getterILCode.Emit(OpCodes.Ret); //Definethesettermethod. MethodBuildersetterMethod=builder.DefineMethod( string.Concat(SetterPrefix,propertyName), propertyMethodAttributes,null,newType[]{propertyType}); //EmittheILcode. //ldarg.0 //ldarg.1 //stfld,_field //ret ILGeneratorsetterILCode=setterMethod.GetILGenerator(); setterILCode.Emit(OpCodes.Ldarg_0); setterILCode.Emit(OpCodes.Ldarg_1); setterILCode.Emit(OpCodes.Stfld,fieldBuilder); setterILCode.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterMethod); propertyBuilder.SetSetMethod(setterMethod); } } }
///<summary> ///Readsdatabaseschemafromquery,generatesassemblyinthememory,andreturnsdynamicobject ///</summary> publicstaticSystem.Collections.IEnumerableDynamicSqlQuery(thisDatabasedatabase,stringsql,paramsobject[]parameters) { TypeBuilderbuilder=DynamicMapper.createTypeBuilder( "MyDynamicAssembly","MyDynamicModule","MyDynamicType"); using(System.Data.IDbCommandcommand=database.Connection.CreateCommand()) { try { database.Connection.Open(); command.CommandText=sql; command.CommandTimeout=command.Connection.ConnectionTimeout; foreach(varparaminparameters) { command.Parameters.Add(param); } using(System.Data.IDataReaderreader=command.ExecuteReader()) { varschema=reader.GetSchemaTable(); foreach(System.Data.DataRowrowinschema.Rows) { stringname=(string)row["ColumnName"]; Typetype=(Type)row["DataType"]; DynamicMapper.createAutoImplementedProperty(builder,name,type); } } } finally { database.Connection.Close(); command.Parameters.Clear(); } } TyperesultType=builder.CreateType(); returndatabase.SqlQuery(resultType,sql,parameters); } privatestaticTypeBuildercreateTypeBuilder( stringassemblyName,stringmoduleName,stringtypeName) { TypeBuildertypeBuilder=AppDomain .CurrentDomain .DefineDynamicAssembly(newAssemblyName(assemblyName), AssemblyBuilderAccess.Run) .DefineDynamicModule(moduleName) .DefineType(typeName,TypeAttributes.Public); typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); returntypeBuilder; } privatestaticvoidcreateAutoImplementedProperty( TypeBuilderbuilder,stringpropertyName,TypepropertyType) { conststringPrivateFieldPrefix="m_"; conststringGetterPrefix="get_"; conststringSetterPrefix="set_"; //Generatethefield. FieldBuilderfieldBuilder=builder.DefineField( string.Concat(PrivateFieldPrefix,propertyName), propertyType,FieldAttributes.Private); //Generatetheproperty PropertyBuilderpropertyBuilder=builder.DefineProperty( propertyName,PropertyAttributes.HasDefault,propertyType,null); //Propertygetterandsetterattributes. MethodAttributespropertyMethodAttributes= MethodAttributes.Public|MethodAttributes.SpecialName| MethodAttributes.HideBySig; //Definethegettermethod. MethodBuildergetterMethod=builder.DefineMethod( string.Concat(GetterPrefix,propertyName), propertyMethodAttributes,propertyType,Type.EmptyTypes); //EmittheILcode. //ldarg.0 //ldfld,_field //ret ILGeneratorgetterILCode=getterMethod.GetILGenerator(); getterILCode.Emit(OpCodes.Ldarg_0); getterILCode.Emit(OpCodes.Ldfld,fieldBuilder); getterILCode.Emit(OpCodes.Ret); //Definethesettermethod. MethodBuildersetterMethod=builder.DefineMethod( string.Concat(SetterPrefix,propertyName), propertyMethodAttributes,null,newType[]{propertyType}); //EmittheILcode. //ldarg.0 //ldarg.1 //stfld,_field //ret ILGeneratorsetterILCode=setterMethod.GetILGenerator(); setterILCode.Emit(OpCodes.Ldarg_0); setterILCode.Emit(OpCodes.Ldarg_1); setterILCode.Emit(OpCodes.Stfld,fieldBuilder); setterILCode.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterMethod); propertyBuilder.SetSetMethod(setterMethod); } }
publicstaticclassDynamicMapper
{
privatestaticDictionary<string,Type>baseEntityTypesByType=newDictionary<string,Type>();publicstaticSystem.Collections.IEnumerableDynamicSqlQuery(thisDatabasedatabase,stringsql,paramsobject[]parameters)
{TyperesultType;if(baseEntityTypesByType.TryGetValue(sql,outresultType))
{
Console.WriteLine("InsideGottheType");
if(parameters!=null)
returndatabase.SqlQuery(resultType,sql,parameters);
returndatabase.SqlQuery(resultType,sql);
}TypeBuilderbuilder=DynamicMapper.createTypeBuilder(
"MyDynamicAssembly","MyDynamicModule","MyDynamicType");using(System.Data.IDbCommandcommand=database.Connection.CreateCommand())
{
try
{
database.Connection.Open();
command.CommandText=sql;
command.CommandTimeout=command.Connection.ConnectionTimeout;
if(parameters!=null)
{
foreach(varparaminparameters)
{
command.Parameters.Add(param);
}
}using(System.Data.IDataReaderreader=command.ExecuteReader())
{
varschema=reader.GetSchemaTable();
foreach(System.Data.DataRowrowinschema.Rows)
{
stringname=(string)row["ColumnName"];
Typetype=(Type)row["DataType"];
varallowNull=(bool)row["AllowDBNull"];
if(allowNull)
{
type=GetNullableType(type);
}
DynamicMapper.createAutoImplementedProperty(builder,name,type);
}
}
}
finally
{
database.Connection.Close();
command.Parameters.Clear();
}
}resultType=builder.CreateType();
baseEntityTypesByType[sql]=resultType;if(parameters!=null)
returndatabase.SqlQuery(resultType,sql,parameters);returndatabase.SqlQuery(resultType,sql);
}privatestaticTypeBuildercreateTypeBuilder(
stringassemblyName,stringmoduleName,stringtypeName)
{
TypeBuildertypeBuilder=AppDomain
.CurrentDomain
.DefineDynamicAssembly(newAssemblyName(assemblyName),
AssemblyBuilderAccess.Run)
.DefineDynamicModule(moduleName)
.DefineType(typeName,TypeAttributes.Public);
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
returntypeBuilder;
}privatestaticvoidcreateAutoImplementedProperty(
TypeBuilderbuilder,stringpropertyName,TypepropertyType)
{
conststringPrivateFieldPrefix="m_";
conststringGetterPrefix="get_";
conststringSetterPrefix="set_";//Generatethefield.
FieldBuilderfieldBuilder=builder.DefineField(
string.Concat(PrivateFieldPrefix,propertyName),
propertyType,FieldAttributes.Private);//Generatetheproperty
PropertyBuilderpropertyBuilder=builder.DefineProperty(
propertyName,PropertyAttributes.HasDefault,propertyType,null);//Propertygetterandsetterattributes.
MethodAttributespropertyMethodAttributes=
MethodAttributes.Public|MethodAttributes.SpecialName|
MethodAttributes.HideBySig;//Definethegettermethod.
MethodBuildergetterMethod=builder.DefineMethod(
string.Concat(GetterPrefix,propertyName),
propertyMethodAttributes,propertyType,Type.EmptyTypes);//EmittheILcode.
//ldarg.0
//ldfld,_field
//ret
ILGeneratorgetterILCode=getterMethod.GetILGenerator();
getterILCode.Emit(OpCodes.Ldarg_0);
getterILCode.Emit(OpCodes.Ldfld,fieldBuilder);
getterILCode.Emit(OpCodes.Ret);//Definethesettermethod.
MethodBuildersetterMethod=builder.DefineMethod(
string.Concat(SetterPrefix,propertyName),
propertyMethodAttributes,null,newType[]{propertyType});//EmittheILcode.
//ldarg.0
//ldarg.1
//stfld,_field
//ret
ILGeneratorsetterILCode=setterMethod.GetILGenerator();
setterILCode.Emit(OpCodes.Ldarg_0);
setterILCode.Emit(OpCodes.Ldarg_1);
setterILCode.Emit(OpCodes.Stfld,fieldBuilder);
setterILCode.Emit(OpCodes.Ret);propertyBuilder.SetGetMethod(getterMethod);
propertyBuilder.SetSetMethod(setterMethod);
}publicstaticTypeGetNullableType(TypeTypeToConvert)
{
//Abortifnotypesupplied
if(TypeToConvert==null)
returnnull;//Ifthegiventypeisalreadynullable,justreturnit
if(IsTypeNullable(TypeToConvert))
returnTypeToConvert;//IfthetypeisaValueTypeandisnotSystem.Void,convertittoaNullable<Type>
if(TypeToConvert.IsValueType&&TypeToConvert!=typeof(void))
returntypeof(Nullable<>).MakeGenericType(TypeToConvert);//Done-noconversion
returnnull;
}
publicstaticboolIsTypeNullable(TypeTypeToTest)
{
//Abortifnotypesupplied
if(TypeToTest==null)
returnfalse;//Ifthisisnotavaluetype,itisareferencetype,soitisautomaticallynullable
//(NOTE:AllformsofNullable<T>arevaluetypes)
if(!TypeToTest.IsValueType)
returntrue;//ReportwhetherTypeToTestisaformoftheNullable<>type
returnTypeToTest.IsGenericType&&TypeToTest.GetGenericTypeDefinition()==typeof(Nullable<>);
}}
相关文章推荐
- 反射-动态加载和使用类型
- 容易被忽略的细节(2):使用泛型类和泛型方法解决【动态类型】问题
- ASP.NET MVC 2.0 in Vs2010 :使用C# 4.0中使用动态类型来传递ViewData
- ASP.NET MVC 2.0 in Vs2010 :使用C# 4.0中使用动态类型来传递ViewData
- 使用dynamic 类型动态调用方法
- ASP.NET MVC 2.0 in Vs2010 :使用C# 4.0中使用动态类型来传递ViewData
- 动态库中使用STL数据类型
- 在Visual Studio 2010中使用C# 4.0的动态类型(转)
- Objective-c使用动态类型检
- objective-c 多态 — 动态类型 id 的使用
- objective-c 多态 ——动态类型 id 的使用(与 C# 的比较说明)
- 动态加载和使用类型
- SQLite使用动态类型系统
- 使用C++构建最简单的动态类型系统
- ABAP--动态创建类型和变量的使用程序样例
- javascript中创建自定义类型的最常见的方式_组合使用构造函数模型和原型模式,动态原型模式
- 使用泛型委声明来动态指派委托的返回类型
- EF.使用反射解决实体类型转换问题
- 动态装载和使用类型
- ABAP--动态创建类型和变量的使用程序样例