码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-11-08 16:35:16      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:des   blog   io   ar   使用   sp   数据   div   on   

动态创建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);

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

标签:des   blog   io   ar   使用   sp   数据   div   on   

原文地址:http://www.cnblogs.com/fred-bao/p/4083504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!