I hate doing this but I've spent way too much time on this. The following is an attempt to convert the c# method to a MethodBuilder. The Result should be the override method for the EntityFramework OnModelCreating using EFCodeFirst.
Here is the method in c# (model names shortened for simplicity)
protected override void OnModelCreating(ModelBuilder modelBu开发者_如何学JAVAilder) {
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Entity<Form>().ToTable("Form<Name>");
modelBuilder.Entity<FormAg>().ToTable("FormAg<Name>");
}
Here's the MethodBuilder I'm currently using:
private static MethodBuilder FormContextBuildMethodOnModelCreating(TypeBuilder type, string formId) {
System.Reflection.MethodAttributes methodAttributes = System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Family | System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.HideBySig;
//method
MethodBuilder OnModelCreating = type.DefineMethod("OnModelCreating", methodAttributes);
//method calls
MethodInfo Conventions = typeof(ModelBuilder).GetMethod("get_Conventions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);
MethodInfo RemoveConventions = typeof(ConventionsConfiguration).GetMethod("Remove", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);
MethodInfo Entity = typeof(ModelBuilder).GetMethod("Entity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);
MethodInfo ToTable1 = typeof(System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<>).MakeGenericType(typeof(Form)).GetMethod("ToTable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(String) }, null);
MethodInfo ToTable2 = typeof(System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<>).MakeGenericType(typeof(FormAg)).GetMethod("ToTable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(String) }, null);
OnModelCreating.SetReturnType(typeof(void));
OnModelCreating.SetParameters(typeof(ModelBuilder));
ParameterBuilder modelBuilder = OnModelCreating.DefineParameter(1, ParameterAttributes.None, "modelBuilder");
ILGenerator Il = OnModelCreating.GetILGenerator();
Il.Emit(OpCodes.Nop);
Il.Emit(OpCodes.Ldarg_1);
Il.Emit(OpCodes.Callvirt, Conventions);
Il.Emit(OpCodes.Callvirt, RemoveConventions);
Il.Emit(OpCodes.Nop);
Il.Emit(OpCodes.Ldarg_1);
Il.Emit(OpCodes.Callvirt, Entity);
Il.Emit(OpCodes.Ldstr, "Form" + formId);
Il.Emit(OpCodes.Callvirt, ToTable1);
Il.Emit(OpCodes.Nop);
Il.Emit(OpCodes.Ldarg_1);
Il.Emit(OpCodes.Callvirt, Entity);
Il.Emit(OpCodes.Ldstr, "FormAg" + formId);
Il.Emit(OpCodes.Callvirt, ToTable2);
Il.Emit(OpCodes.Nop);
Il.Emit(OpCodes.Ret);
return OnModelCreating;
}
The OpCodes were gleaned from reflector il of the above c# code. For the life of me I can not figure out what is wrong here. I've narrowed the issue down to this method as all the other properties and what not are built correctly. I can return an empty body (Nop
+ Ret
) and it works fine...
Any attempt to use the resulting type causes the following error:
An attempt was made to load a program with an incorrect format.
Any help would be greatly appreciated.
Just gonna answer this question to close it.
I created another class that inherits from the base class that contains the OnModelCreating with a new constructor that passes in the formId.
精彩评论