首页 > 代码库 > EntityFramework动态创建模型:System.Reflection.Emit + Code First

EntityFramework动态创建模型:System.Reflection.Emit + Code First

动态创建Entity Framework模型并且创建数据库

使用System.Reflection.Emit+Code First model创建以下的一个实体类和DbContext并且创建数据库:

 1 using System; 2  3 public class Blog 4  5 { 6  7 private int id; 8  9 private string name;10 11 public int ID12 13 {14 15 get16 17 {18 19 return this.id;20 21 }22 23 set24 25 {26 27 this.id = value;28 29 }30 31 }32 33 public string Name34 35 {36 37 get38 39 {40 41 return this.name;42 43 }44 45 set46 47 {48 49 this.name = value;50 51 }52 53 }54 55 } using System;using System.Data.Entity;public class Sample20141106 : DbContext{private DbSet<Blog> blogs;public DbSet<Blog> Blogs{get{return this.blogs;}set{this.blogs = value;}}}

 

1.创建类所在的程序集合module:

AppDomain myDomain = Thread.GetDomain();AssemblyName myAsmName = new AssemblyName();myAsmName.Name = "Sample20141106";// To generate a persistable assembly, specify AssemblyBuilderAccess.RunAndSave.ssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave);// Generate a persistable single-module assembly.ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");

 

 

2.创建Blog实体类:

 

创建类型:

 TypeBuilder BlogTypeBuilder = myModBuilder.DefineType("Blog", TypeAttributes.Public); 

 

创建ID和Name properties:(这个应该可以考虑写成同样方法,传入类型和类型名称)

FieldBuilder idBldr = BlogTypeBuilder.DefineField("id", typeof(int), FieldAttributes.Private);            FieldBuilder nameBldr = BlogTypeBuilder.DefineField("name", typeof(string), FieldAttributes.Private);             PropertyBuilder idPropBldr = BlogTypeBuilder.DefineProperty("ID", PropertyAttributes.HasDefault, typeof(int), null);            PropertyBuilder namePropBldr = BlogTypeBuilder.DefineProperty("Name", PropertyAttributes.HasDefault, typeof(string), null);             MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;             MethodBuilder idGetPropMthdBldr = BlogTypeBuilder.DefineMethod("get_ID", getSetAttr, typeof(int), Type.EmptyTypes);            ILGenerator idGetIL = idGetPropMthdBldr.GetILGenerator();            idGetIL.Emit(OpCodes.Ldarg_0);            idGetIL.Emit(OpCodes.Ldfld, idBldr);            idGetIL.Emit(OpCodes.Ret);            MethodBuilder idSetPropMthdBldr = BlogTypeBuilder.DefineMethod("set_ID", getSetAttr, null, new Type[] { typeof(int) });            ILGenerator idSetIL = idSetPropMthdBldr.GetILGenerator();            idSetIL.Emit(OpCodes.Ldarg_0);            idSetIL.Emit(OpCodes.Ldarg_1);            idSetIL.Emit(OpCodes.Stfld, idBldr);            idSetIL.Emit(OpCodes.Ret);            idPropBldr.SetGetMethod(idGetPropMthdBldr);            idPropBldr.SetSetMethod(idSetPropMthdBldr);             MethodBuilder nameGetPropMthdBldr = BlogTypeBuilder.DefineMethod("get_Name", getSetAttr, typeof(int), Type.EmptyTypes);            ILGenerator nameGetIL = nameGetPropMthdBldr.GetILGenerator();            nameGetIL.Emit(OpCodes.Ldarg_0);            nameGetIL.Emit(OpCodes.Ldfld, nameBldr);            nameGetIL.Emit(OpCodes.Ret);            MethodBuilder nameSetPropMthdBldr = BlogTypeBuilder.DefineMethod("set_Name", getSetAttr, null, new Type[] { typeof(int) });            ILGenerator nameSetIL = nameSetPropMthdBldr.GetILGenerator();            nameSetIL.Emit(OpCodes.Ldarg_0);            nameSetIL.Emit(OpCodes.Ldarg_1);            nameSetIL.Emit(OpCodes.Stfld, nameBldr);            nameSetIL.Emit(OpCodes.Ret);            namePropBldr.SetGetMethod(nameGetPropMthdBldr);            namePropBldr.SetSetMethod(nameSetPropMthdBldr);

 生成类型到内存中,这个类型在后面生成DbContext有用

 Type blogType = BlogTypeBuilder.CreateType();

 2.创建DbContxt类型: 

构造类型:

TypeBuilder Sample20141106TypeBuilder = myModBuilder.DefineType("Sample20141106", TypeAttributes.Public);Sample20141106TypeBuilder.SetParent(typeof(DbContext));//生成的类型继承DbContext, 在生成程序集的时候会自动引用EntiyFrame.dll.

 构造DbSet<T>属性: 

FieldBuilder blogFieldBuilder = Sample20141106TypeBuilder.DefineField("blogs", typeof(DbSet<>).MakeGenericType(blogType), FieldAttributes.Private);             PropertyBuilder blogPropBldr = Sample20141106TypeBuilder.DefineProperty("Blogs", PropertyAttributes.HasDefault, typeof(DbSet<>).MakeGenericType(blogType), null);             MethodBuilder blogGetPropMthdBldr = Sample20141106TypeBuilder.DefineMethod("get_Blog", getSetAttr, typeof(DbSet<>).MakeGenericType(blogType), Type.EmptyTypes);            ILGenerator blogGetIL = blogGetPropMthdBldr.GetILGenerator();            blogGetIL.Emit(OpCodes.Ldarg_0);            blogGetIL.Emit(OpCodes.Ldfld, blogFieldBuilder);            blogGetIL.Emit(OpCodes.Ret);            MethodBuilder blogSetPropMthdBldr = Sample20141106TypeBuilder.DefineMethod("set_Blog", getSetAttr, null, new Type[] { typeof(DbSet<>).MakeGenericType(blogType) });            ILGenerator blogSetIL = blogSetPropMthdBldr.GetILGenerator();            blogSetIL.Emit(OpCodes.Ldarg_0);            blogSetIL.Emit(OpCodes.Ldarg_1);            blogSetIL.Emit(OpCodes.Stfld, blogFieldBuilder);            blogSetIL.Emit(OpCodes.Ret);            blogPropBldr.SetGetMethod(blogGetPropMthdBldr);            blogPropBldr.SetSetMethod(blogSetPropMthdBldr);

 生成DbContext类型到内存:

Type Sample20141106Type = Sample20141106TypeBuilder.CreateType();

 可以选择将模型保存到dll中:

 myAsmBuilder.Save(myAsmName.Name + ".dll");

然后可以在其他project中引用。或者用反射直接生成数据库:

Type Sample20141106 = BuildDynamicTypeWithProperties();object db = Activator.CreateInstance(Sample20141106);Type Database = Sample20141106.GetProperty("Database").GetValue(db).GetType();object database = Sample20141106.GetProperty("Database").GetValue(db);

  MethodInfo CreateIfNotExists = Database.GetMethod("CreateIfNotExists");

  CreateIfNotExists.Invoke(database, null);

EntityFramework动态创建模型:System.Reflection.Emit + Code First