В результате метода MethodBuilder для Entity Framework программа «неверный формат» - PullRequest
0 голосов
/ 08 января 2011

Я ненавижу это делать, но я потратил слишком много времени на это. Ниже приведена попытка преобразовать метод c # в MethodBuilder. Результатом должен быть метод переопределения для EntityFramework OnModelCreating с использованием EFCodeFirst.

Вот метод в c # (названия моделей сокращены для простоты)

protected override void OnModelCreating(ModelBuilder modelBuilder) {
    modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
    modelBuilder.Entity<Form>().ToTable("Form<Name>");
    modelBuilder.Entity<FormAg>().ToTable("FormAg<Name>");
}

Вот метод, который я сейчас использую:

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

OpCodes были получены из рефлектора il вышеуказанного кода C #. По жизни я не могу понять, что здесь не так. Я сузил проблему до этого метода, так как все остальные свойства и что не построены правильно. Я могу вернуть пустое тело (Nop + Ret), и оно отлично работает ...

Любая попытка использовать результирующий тип вызывает следующую ошибку: An attempt was made to load a program with an incorrect format.

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 30 марта 2011

Просто собираюсь ответить на этот вопрос, чтобы закрыть его.

Я создал другой класс, который наследуется от базового класса, который содержит OnModelCreating с новым конструктором, который передает formId.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...