[EF] - 动态创建模型: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 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);

转载于:https://www.cnblogs.com/fred-bao/p/4083504.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值