Dynamically create an Entity Framework model and create a database
Use System. Reflection. Emit + Code First model to create an object class and DbContext and create a database:
1 using System; 2 3 public class Blog 4 5 {6 7 private int id; 8 9 private string name; 10 11 public int ID12 13 {14 15 get16 17 {18 19 return this. id; 20 21} 22 23 set24 25 {26 27 this. id = value; 28 29} 30 31} 32 33 public string Name34 35 {36 37 get38 39 {40 41 return this. name; 42 43} 44 45 set46 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. Create the program set module where the class is located:
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. Create a Blog entity class:
Creation type:
TypeBuilder BlogTypeBuilder = myModBuilder. DefineType ("Blog", TypeAttributes. Public );
Create ID and Name properties :( this should be considered as the same method, INPUT type and type Name)
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. ldtil, 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. sttil, 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 );
Generate the type to the memory. This type is useful when DbContext is generated later.
Type blogType = BlogTypeBuilder. CreateType ();
2. Create the DbContxt type:
Construction type:
TypeBuilder Sample20141106TypeBuilder = myModBuilder. defineType ("Sample20141106", TypeAttributes. public); Sample20141106TypeBuilder. setParent (typeof (DbContext); // The generated type inherits DbContext. The EntiyFrame is automatically referenced when the assembly is generated. dll.
Construct the DbSet <T> attribute:
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 );
Generate DbContext type to memory:
Type Sample20141106Type = Sample20141106TypeBuilder. CreateType ();
You can save the model to the dll:
MyAsmBuilder. Save (myAsmName. Name + ". dll ");
It can be referenced in other projects. Or directly generate a database using reflection:
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 dynamic model creation: System. Reflection. Emit + Code First