您的位置:首页 > 其它

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<>);
}}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: