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 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

EntityFramework动态创建模型:System.Reflection.Emit + Code First的相关文章

System.Reflection.Emit学习

C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于System.Reflection.Emit命名空间下.反射,我们可以取得形如程序集包含哪些类型,类型包含哪些方法等等大量的信息,而Emit则可以在运行时动态生成代码. 二.IL代码解析 以下代码为例: 1 static void Main(string[] args) 2 { 3 int i = 1; 4

[1]System.Reflection.Emit

在这个大数据/云计算/人工智能研发普及的时代,Python的崛起以及Javascript的前后端的侵略,程序员与企业似乎越来越青睐动态语言所带来的便捷性与高效性,即使静态语言在性能,错误检查等方面的优于静态语言.对于.NETer来说,.NET做为一门静态语言,我们不仅要打好.NET的基本功,如基本类型/语法/底层原理/错误检查等知识,也要深入理解.NET的一些高级特性,来为你的工作减轻负担和提高代码质量. ok,咱们今天开始聊一聊.NET中的Emit. 一.什么是Emit? Emit含义为发出.

Ember.js之动态创建模型

本人原文地址发布在:点击这里 What problem did we meet? As ember document suggestion, we may define a model as a structure which will be used for serialization or deserialization to request from RESTful-based server or others. if we define a model as: 1 var Person

第二节:创建模型,使用Code First,配置映射关系(一)

这一节,实现模型的创建,配置映射关系 使用Code First数据迁移. 创建模型 一,首先创建几个接口:实体接口,聚合根接口,值对象接口 1,实体接口: 2,聚合根接口: 3,值对象接口: 二,模型 这里我们的业务场景是:一个用户可以创建一个博客,在博客中可以写多篇文章,一篇文章只能有一个评论,(练习配置映射关系)由于格式的原因我移除了注释信息 用户: public class UserInfo: IAggregationRoot { #region 用户实体 [Key][DatabaseGe

YII2框架动态创建表模型

在YII2中,每个表对应一个model类 在开发过程中,我们在填写一个大型表单的时候,表单里有N个select下拉列表,每个下拉select来自于不同的表: 如果要在程序里用实例化引入这些model类,估计又是N个use引用,而且还需要写查询方法. 所以铁牛在使用过程中,就思考能否创建动态表模型来应用到我们的开发中. 代码见下: namespace backend\classes; //创建动态表模型 //在使用调用某些表数据的时候,勿需创建模型既可调用表数据,生成select //$selec

【C#基础】System.Reflection (反射)

在使用.NET创建的程序或组件时,元数据(metadata)和代码(code)都存储于"自成一体"的单元中,这个单元称为装配件.我们可以在程序运行期间访问这些信息.在System.Reflection中有这样一个class----Assembly,我们可以通过它来加载一个装配件.方法如下:Assembly assm=Assembly.LoadFrom(fileName);其中filename是要加载的装配件的文件名称(带路径).接下来,我们就可以通过使用System.Reflectio

C# System.Reflection (反射)

在使用.NET创建的程序或组件时,元数据(metadata)和代码(code)都存储于"自成一体"的单元中,这个单元称为装配件.我们可以在程序运行期间访问这些信息. 在System.Reflection中有这样一个class----Assembly,我们可以通过它来加载一个装配件.方法如下: Assembly assm=Assembly.LoadFrom(fileName); 其中filename是要加载的装配件的文件名称(带路径). 接下来,我们就可以通过使用System.Refle

C#动态执行字符串(动态创建代码)

在编写C#程序的时候,有时我们需要动态生成一些代码并执行.然而C#不像JavaScript有一个Eval函数,可以动态的执行代码.所有这些功能都要我们自己去完成.如下是实例. 动态创建代码: using System; using System.Data; using System.Configuration; using System.Text; using System.CodeDom.Compiler; using Microsoft.CSharp; using System.Reflec

在代码中动态创建控件无法保存状态的问题

在网上找了点资料,算是明白了,这是我觉得有帮助的文章: 原文:http://blog.csdn.net/keleloveni/archive/2007/03/15/1530300.aspx 引文: 今天偶然看到有篇文章谈到了相关的问题,终于又解决了一个自己不是很明白的东西. 页面生命周期中的第一个阶段是实例化,在这个阶段中,自动生成的类会根据页面的 HTML 部分中定义的静态控件构建控件层次结构.构造控件层次结构时,声明性语法中指定的值会赋给添加的每个控件的属性.实例化之后是初始化阶段,在这个阶