5

I really can't figure this one out...

I'm trying to achieve the following result using reflection:

_builder.Entity<Post>().HasKey(p => p.Id);

Let me introduce the variables... _builder is of type DbModelBuilder and Post has a property Id of type Guid.

In the code below, contentType wraps a 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 definition might help:

public EntityTypeConfiguration<TEntityType> HasKey<TKey>(Expression<Func<TEntityType, TKey>> keyExpression);

... where TEntityType should be of type Post and TKey of type Guid ...

Exception of type TargetException is thrown (on the last call to Invoke above) :

Object does not match target type.

I have tried every idea I could come up with and still I can't match the target type.

Any help is appreciated.

8
  • Not to be blond here, but shouldnt your last invoke's instance parameter be config rather than _builder? :) Commented Oct 19, 2011 at 3:24
  • Just curious since i find the idea intriguing. Are you trying to to create some kind of dynamic EF ModelBuilder? Commented Oct 19, 2011 at 3:28
  • haha Skeet is still sleeping, allowing me to gain some points ;) Commented Oct 19, 2011 at 3:28
  • Yes, this code basically allows you to add Types at runtime and have them persisted in a SQL database, the model checked for database recreation, etc... Dynamic EF ModelBuilder yep! Commented Oct 19, 2011 at 3:31
  • Very interresting, i've been looking at a something similar for a trusted plugin environment and where they can store their data.... Are you planning on making this an opensource project? Commented Oct 19, 2011 at 3:32

2 Answers 2

2

In your last call to Invoke, you specified the wrong instance parameter. Should be 'config' rather than '_builder'

Sign up to request clarification or add additional context in comments.

Comments

0

Silly me, I have no excuses...

How-to Entity Framework & Reflection:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.