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

[EF] - 动态创建模型:System.Reflection.Emit + Code First的更多相关文章

  1. System.Reflection.Emit学习

    C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于Syste ...

  2. C#反射发出System.Reflection.Emit学习

    一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于System.Reflection.Emit命名空间下.反射,我们可以取得形如程序集 ...

  3. System.Reflection.Emit摘记

    动态类型在.net中都是用什么类型来表示的.程序集:System.Reflection.Emit.AssemblyBuilder(定义并表示动态程序集)构造函数:System.Reflection.E ...

  4. Ember.js之动态创建模型

    本人原文地址发布在:点击这里 What problem did we meet? As ember document suggestion, we may define a model as a st ...

  5. 【译】Reflection.Emit vs. CodeDOM

    原文:http://ayende.com/blog/1606/reflection-emit-vs-codedom Both technologies allow you to generate ex ...

  6. 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类

    秒懂C#通过Emit动态生成代码   首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...

  7. C#动态创建和动态使用程序集、类、方法、字段等

    C#动态创建和动态使用程序集.类.方法.字段等 分类:技术交流 (3204)  (3)   首先需要知道动态创建这些类型是使用的一些什么技术呢?其实只要相关动态加载程序集呀,类呀,都是使用反射,那么动 ...

  8. [读行者][学习LinqExpression和Reflection(Emit)]阅读TypeBuilderSample之ExampleFromTheArticle

    前言 关于”读行者“ 俗语有云:"读万卷书,行万里路“.多读一些优秀代码,不仅可以锻炼我们读代码的能力(便于维护或相互交流),还可以吸取很多我们成长所需的知识点.多读,才能开阔我们的眼界,才 ...

  9. Silverlight中如何自己写方法将DataTable转换为PagedCollectionView数据(动态创建类)

    将DataTable转换为PagedCollectionView数据,我们可以借用DataTable的GetBindableData()方法,如下: DataTable dt=new DataTabl ...

随机推荐

  1. E - Knapsack 2 题解(超大01背包)

    题目链接 题目大意 给你一n(n<=100)个物品,物品价值最大为1e3,物品体积最多为1e9,背包最大为1e9 题目思路 如果按照平常的背包来算那么时间复杂度直接O(1e11) 这个你观察就发 ...

  2. lambda表达式中无法抛出受检异常!

    抛出受检异常的时候,我们的接口应该带上throw关键字,但通过lambda表达式实现的Consumer的accept方法并不带有关键字,因此在lambda表达式中不能抛出受检异常必须把它吃掉

  3. Oracle 11g改密码有效期

    oracle 11g,密码默认有效期为180天,设置为不过期,可在线操作. 步骤: -->>进入oracle用户 su - oracle -->>已sys超级用户登录sqlpl ...

  4. Android自带图标库

    Java Usage example: myMenuItem.setIcon(android.R.drawable.ic_menu_save); Resource Usage example: and ...

  5. this大全,还有谁??????!!!!!!!

    this在函数调用时创建,一般的对象没有this,全局window可以理解为一个函数,他有一个全局this JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系. 函数里thi ...

  6. 第15.8节 PyQt入门学习:Designer的界面功能介绍

    进入Qt Designer以后,打开或新建一个ui文件,Qt Designer窗口展示的页面如下图所示: 老猿将界面各部分使用红色数字进行标记,按照数字顺序各区域对应功能分别为: 1.界面元素控件区域 ...

  7. PyQt(Python+Qt)学习随笔:Qt Designer中窗口对象的windowFilePath属性

    windowFilePath属性仅对窗口对象有效,用于关联一个窗口和对应的文件及路径. 当窗口没有设置标题属性的情况下,则窗口标题展示展示windowFilePath对应的文件名的信息(路径信息不展示 ...

  8. Hbase 简单封装(Hbase 2.0+ API)

    前言 封装了一些常用的方法 添加一行数据 创建表(单列族) 创建表(多列族) 删除表 判断表是否存在 获取一行数据(根据rowkey) 获取某个列族某个列的某行数据 打印出result(方便展示数据) ...

  9. 【Docker】 .Net Core 3.1 webapi 集成EF Code First,使用MySql进行业务操作 、配置swagger (三)

    系列目录: [Docker] CentOS7 安装 Docker 及其使用方法 ( 一 ) [Docker] 使用Docker 在阿里云 Centos7 部署 MySQL 和 Redis (二) [D ...

  10. 题解-CF1396C Monster Invaders

    题面 CF1396C Monster Invaders 有 \(n\) 层关卡,每层有 \(a_i\) 个小怪(\(1\) 血)和 \(1\) 个老怪(\(2\) 血).有三种武器:\(1\) 武器每 ...