LINQ On DbContext.Set()

2019-06-03 16:00发布

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?

3条回答
放我归山
2楼-- · 2019-06-03 16:05

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.

查看更多
beautiful°
3楼-- · 2019-06-03 16:10

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.

查看更多
三岁会撩人
4楼-- · 2019-06-03 16:25

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!

查看更多
登录 后发表回答