Created
May 1, 2013 20:11
-
-
Save timhobbs/5497983 to your computer and use it in GitHub Desktop.
EF 4.1 SqlQuery return Dynamic
http://www.codeproject.com/Articles/206416/Use-dynamic-type-in-Entity-Framework-4-1-SqlQuery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Reads database schema from query, generates assembly in the memory, and returns dynamic object | |
/// </summary> | |
public static System.Collections.IEnumerable DynamicSqlQuery(this Database database, string sql, params object[] parameters) | |
{ | |
TypeBuilder builder = DynamicMapper.createTypeBuilder( | |
"MyDynamicAssembly", "MyDynamicModule", "MyDynamicType"); | |
using (System.Data.IDbCommand command = database.Connection.CreateCommand()) | |
{ | |
try | |
{ | |
database.Connection.Open(); | |
command.CommandText = sql; | |
command.CommandTimeout = command.Connection.ConnectionTimeout; | |
foreach (var param in parameters) | |
{ | |
command.Parameters.Add(param); | |
} | |
using (System.Data.IDataReader reader = command.ExecuteReader()) | |
{ | |
var schema = reader.GetSchemaTable(); | |
foreach (System.Data.DataRow row in schema.Rows) | |
{ | |
string name = (string)row["ColumnName"]; | |
Type type = (Type)row["DataType"]; | |
DynamicMapper.createAutoImplementedProperty(builder, name, type); | |
} | |
} | |
} | |
finally | |
{ | |
database.Connection.Close(); | |
command.Parameters.Clear(); | |
} | |
} | |
Type resultType = builder.CreateType(); | |
return database.SqlQuery(resultType, sql, parameters); | |
} | |
private static TypeBuilder createTypeBuilder( | |
string assemblyName, string moduleName, string typeName) | |
{ | |
TypeBuilder typeBuilder = AppDomain | |
.CurrentDomain | |
.DefineDynamicAssembly(new AssemblyName(assemblyName), | |
AssemblyBuilderAccess.Run) | |
.DefineDynamicModule(moduleName) | |
.DefineType(typeName, TypeAttributes.Public); | |
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); | |
return typeBuilder; | |
} | |
private static void createAutoImplementedProperty( | |
TypeBuilder builder, string propertyName, Type propertyType) | |
{ | |
const string PrivateFieldPrefix = "m_"; | |
const string GetterPrefix = "get_"; | |
const string SetterPrefix = "set_"; | |
// Generate the field. | |
FieldBuilder fieldBuilder = builder.DefineField( | |
string.Concat(PrivateFieldPrefix, propertyName), | |
propertyType, FieldAttributes.Private); | |
// Generate the property | |
PropertyBuilder propertyBuilder = builder.DefineProperty( | |
propertyName, PropertyAttributes.HasDefault, propertyType, null); | |
// Property getter and setter attributes. | |
MethodAttributes propertyMethodAttributes = | |
MethodAttributes.Public | MethodAttributes.SpecialName | | |
MethodAttributes.HideBySig; | |
// Define the getter method. | |
MethodBuilder getterMethod = builder.DefineMethod( | |
string.Concat(GetterPrefix, propertyName), | |
propertyMethodAttributes, propertyType, Type.EmptyTypes); | |
// Emit the IL code. | |
// ldarg.0 | |
// ldfld,_field | |
// ret | |
ILGenerator getterILCode = getterMethod.GetILGenerator(); | |
getterILCode.Emit(OpCodes.Ldarg_0); | |
getterILCode.Emit(OpCodes.Ldfld, fieldBuilder); | |
getterILCode.Emit(OpCodes.Ret); | |
// Define the setter method. | |
MethodBuilder setterMethod = builder.DefineMethod( | |
string.Concat(SetterPrefix, propertyName), | |
propertyMethodAttributes, null, new Type[] { propertyType }); | |
// Emit the IL code. | |
// ldarg.0 | |
// ldarg.1 | |
// stfld,_field | |
// ret | |
ILGenerator setterILCode = 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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment