#c# #entity-framework #generics #reflection #lambda
#c# #entity-framework #общие #отражение #лямбда
Вопрос:
Я действительно не могу понять это…
Я пытаюсь достичь следующего результата, используя отражение:
_builder.Entity<Post>().HasKey(p => p.Id);
Позвольте мне представить переменные… _builder
имеет тип DbModelBuilder
и Post
имеет свойство Id
типа Guid
.
В приведенном ниже коде contentType
оборачивается System.Type
:
var config = _builder.GetType()
.GetMethod("Entity")
.MakeGenericMethod(contentType.Type)
.Invoke(_builder, null);
var hasKey = config.GetType().GetMethod("HasKey");
var expressionKey = typeof(Expression<>)
.MakeGenericType(typeof(Func<,>)
.MakeGenericType(contentType.Type, typeof(Guid)));
var paramEx = Expression.Parameter(contentType.Type, "t");
var lambdaEx = Expression.Lambda(Expression.Property(paramEx, "Id"), paramEx);
hasKey.MakeGenericMethod(typeof(Guid))
.Invoke(_builder, new[] { lambdaEx });
HasKey
определение может помочь:
public EntityTypeConfiguration<TEntityType> HasKey<TKey>(Expression<Func<TEntityType, TKey>> keyExpression);
… где TEntityType
должно быть типа Post
и TKey
типа Guid
…
Генерируется исключение типа TargetException
(при последнем вызове для вызова выше) :
Объект не соответствует целевому типу.
Я перепробовал все идеи, которые мог придумать, и все равно не могу подобрать целевой тип.
Любая помощь приветствуется.
Комментарии:
1. Чтобы не быть блондином здесь, но не должен ли параметр экземпляра вашего последнего вызова быть config, а не _builder ? 🙂
2. Просто любопытно, так как я нахожу идею интригующей. Вы пытаетесь создать какой-то динамический EF ModelBuilder?
3. ха-ха-ха, тарелочка все еще спит, что позволяет мне набрать несколько очков 😉
4. Да, этот код в основном позволяет добавлять типы во время выполнения и сохранять их в базе данных SQL, модель проверяется на воссоздание базы данных и т.д… Динамический EF ModelBuilder да!
5. Очень интересно, я искал что-то подобное для доверенной среды плагинов и где они могут хранить свои данные…. Планируете ли вы сделать это проектом с открытым исходным кодом?
Ответ №1:
В вашем последнем вызове Invoke вы указали неправильный параметр экземпляра. Должно быть ‘config’, а не ‘_builder’
Ответ №2:
Глупый я, у меня нет оправданий…
How-to Entity Framework amp; отражение:
var config = _builder.GetType()
.GetMethod("Entity")
.MakeGenericMethod(contentType.Type)
.Invoke(_builder, null);
var hasKey = config.GetType().GetMethod("HasKey");
var expressionKey = typeof(Expression<>)
.MakeGenericType(typeof(Func<,>)
.MakeGenericType(contentType.Type, typeof(Guid)));
var paramEx = Expression.Parameter(contentType.Type, "t");
var lambdaEx = Expression.Lambda(Expression.Property(paramEx, "Id"), paramEx);
hasKey.MakeGenericMethod(typeof(Guid))
.Invoke(config, new[] { lambdaEx });