[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);
[EF] - 动态创建模型:System.Reflection.Emit + Code First的更多相关文章
- System.Reflection.Emit学习
C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于Syste ...
- C#反射发出System.Reflection.Emit学习
一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于System.Reflection.Emit命名空间下.反射,我们可以取得形如程序集 ...
- System.Reflection.Emit摘记
动态类型在.net中都是用什么类型来表示的.程序集:System.Reflection.Emit.AssemblyBuilder(定义并表示动态程序集)构造函数:System.Reflection.E ...
- Ember.js之动态创建模型
本人原文地址发布在:点击这里 What problem did we meet? As ember document suggestion, we may define a model as a st ...
- 【译】Reflection.Emit vs. CodeDOM
原文:http://ayende.com/blog/1606/reflection-emit-vs-codedom Both technologies allow you to generate ex ...
- 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类
秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...
- C#动态创建和动态使用程序集、类、方法、字段等
C#动态创建和动态使用程序集.类.方法.字段等 分类:技术交流 (3204) (3) 首先需要知道动态创建这些类型是使用的一些什么技术呢?其实只要相关动态加载程序集呀,类呀,都是使用反射,那么动 ...
- [读行者][学习LinqExpression和Reflection(Emit)]阅读TypeBuilderSample之ExampleFromTheArticle
前言 关于”读行者“ 俗语有云:"读万卷书,行万里路“.多读一些优秀代码,不仅可以锻炼我们读代码的能力(便于维护或相互交流),还可以吸取很多我们成长所需的知识点.多读,才能开阔我们的眼界,才 ...
- Silverlight中如何自己写方法将DataTable转换为PagedCollectionView数据(动态创建类)
将DataTable转换为PagedCollectionView数据,我们可以借用DataTable的GetBindableData()方法,如下: DataTable dt=new DataTabl ...
随机推荐
- JQuery 和 Bootstrap
https://jquery.com/ 1. JQuery 的基础语法 $(select).action() 2. 查找标签 基本选择器 class选择器: $(".className&q ...
- KNN 算法-实战篇-如何识别手写数字
公号:码农充电站pro 主页:https://codeshellme.github.io 上篇文章介绍了KNN 算法的原理,今天来介绍如何使用KNN 算法识别手写数字? 1,手写数字数据集 手写数字数 ...
- fist-第六天冲刺随笔
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...
- SQL Alias模板
再记不住的话就扇自己巴掌 SELECT * FROM class1 c INNER JOIN class2 p ON c.id = p.id INNER JOIN class3 s ON c.id = ...
- 第14.15节 爬虫实战1:使用Python和selenium实现csdn博文点赞
写在前面:本文仅供参考学习,请勿用作它途,禁止转载! 在开始学爬虫时,学习了csdn博客专家(id:明天依旧可好 | 柯尊柏)<实战项目二:实现CSDN自动点赞>的文章,文章介绍了通过Py ...
- PyQt(Python+Qt)学习随笔:model/view架构中类QStandardItemModel的使用方法
老猿Python博文目录 老猿Python博客地址 一.概述 QStandardItemModel是QAbstractItemModel的派生类,用于在Model/View架构中存储自定义数据的通用模 ...
- flask加载配置文件的三种方法
1.第一种方法也是我们最长用到的,包括我们项目中也是采用第一种的方法,加载配置文件 配置信息全部写在config.py里面,在主app.py的文件中写入 import config app.confi ...
- Dr.COM获取用户属性超时!请检查防火墙配置允许UDP 61440端口。怎么解决
最近校园网老是出问题,看到好多同学都遇到了下面的问题,我就来说一下我的解决方法.(目前我认识的有三个同学遇到了这样的情况,用这个方法都解决了,但不一定对每个人都有效) 首先登陆net.scut.edu ...
- 【题解】HDU4625 JZPTREE
题目链接 题意 给定一棵 n 点的树,定义 \(dis(u,v)\) 为树上路径长度.对于每个点,定义 \(E_u=\sum_{v=1}^n dis(u,v)^k\) ,其中 k 为给定数. 求每个 ...
- NOI 2020 D1T3 本人题解
我看了出题人本题的做法,感觉很难写,就自己胡了一个\(O((n + m) \sqrt n)\)的做法. 第一步我的想法与出题人一样,都是考虑容斥降维.对第\(i\)组询问,我们枚举两个事件中较大的一个 ...