动态创建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 ID 12 13 { 14 15 get 16 17 { 18 19 return this.id; 20 21 } 22 23 set 24 25 { 26 27 this.id = value; 28 29 } 30 31 } 32 33 public string Name 34 35 { 36 37 get 38 39 { 40 41 return this.name; 42 43 } 44 45 set 46 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);
时间: 2024-11-05 11:42:36