1

So, basically I am trying to get a DbSet returned from entity name (string). This is how far I have gotten:

var customers = db.Set(Type.GetType("App.Model.Customer, 
                                     App.Model, 
                                     Version=1.0.0.0, 
                                     Culture=neutral, 
                                     PublicKeyToken=null"));

But then I cannot perform other LINQ like Any() or Single(). Why is that and how can I change it to do so?

8
  • 1
    possible duplicate of Querying against DbContext.Set(TypeVariable) in Entity Framework Commented Oct 22, 2014 at 11:44
  • @Adrian Seems like you understand the problem. Mind briefly explaining it here? Commented Oct 22, 2014 at 11:56
  • 1
    @Md.lbrahim what in the linked question did you not understand? It seems as though that question and answer explains this issue pretty well.. Commented Oct 22, 2014 at 12:15
  • To summarise, can't use Linq on DbContext.Set(TypeVariable) because it doesn't return DbSet<TEntity> but a DbSet meaning there is no type that can be inferred to use with Linq methods. You can instead use DbContext.Set<TEntity>() an invoke it as per the given answer which injects your type using reflection. You will then be able to use Linq. Commented Oct 22, 2014 at 12:28
  • @Default I did not, I am afraid. I don't get why would I be concerned with Local and what is IActionTarget? It would help if you could explain briefly here please. Commented Oct 22, 2014 at 12:29

3 Answers 3

6

The non-generic overload of DbContext.Set returns an equally non-generic DbSet. One of the interfaces this class implements is IQueryable, again, non generic. That's the reason why it can't serve as input to any of these LINQ extension method that are defined on the generic type IQueryable<T>.

So in fact, if you still want to use LINQ, you only postpone the moment when you have to convert to a generic IQueryable. You could do...

var customers = db.Set(Type.GetType(...)).Cast<Customer>().Where(c => ...)

...but then of course you lose the whole point of defining the type dynamically, at runtime.

Once you start dynamically, you have to continue dynamically. One way to do that is by adding System.Linq.Dynamic to your project. Then you can write queries like...

var customers = db.Set(Type.GetType(...)).Where("CustomerId = @0", 1);

...which will return you the Customer (wrapped in an IQueryable<Customer>) having CustomerId == 1.

You can even use the Find method:

var customer = db.Set(Type.GetType(...)).Find(1);

This will return a single Customer instance.

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

Comments

0

With the requirements you have, no, if the requirements were to change you might be able to work around it. If you get your type as string at runtime, how do you believe you could possibly program against it before you even compile the code?

Static typing need static types to work, you can do some ninja dynamics with interfaces to get around part of it, but your question provides no such information.

3 Comments

All I am getting is the name as string and I have to work against that. If it is required for me to use dynamic then so be it. Any working solution is helpful for me at this point. Thanks.
Then you need some kind of minimal interface you know the type will inherit from? Do you have such?
I don't currently. But it shouldn't be too difficult. I will just have my models inherit from an interface for example.
0

Try casting the non-generic IQueryable to a generic (where the generic property is a super class or even just object), e.g.:

((IQueryable<object>)context.Set(Type.GetType(...))).Count();

This worked for me!

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.