LINQ On DbContext.Set()

本文关键字:Set DbContext On LINQ | 更新日期: 2023-09-27 18:27:22

所以,基本上我试图从实体名称(字符串(返回DbSet。这就是我所走多远的:

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

但是我无法执行其他 LINQ,例如 Any()Single() 。为什么会这样,我该如何更改它来这样做?

LINQ On DbContext.Set()

DbContext.Set的非泛型重载返回一个同样非泛型的DbSet。此类实现的接口之一是 IQueryable ,同样,非泛型。这就是为什么它不能用作泛型类型 IQueryable<T> 上定义的任何这些 LINQ 扩展方法的输入的原因。

所以实际上,如果你仍然想使用LINQ,你只会推迟你必须转换为泛型IQueryable的时刻。你可以做...

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

。但是,当然,您就失去了在运行时动态定义类型的全部意义。

一旦你动态地开始,你必须动态地继续。一种方法是将System.Linq.Dynamic添加到项目中。然后,您可以编写诸如...

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

。这将返回您具有CustomerId == 1 Customer(包裹在IQueryable<Customer>中(。

您甚至可以使用 Find 方法:

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

这将返回单个Customer实例。

有了你所拥有的要求,不,如果需求发生变化,你也许能够解决它。如果你在运行时将类型作为字符串,你如何相信在编译代码之前你可以针对它进行编程?

静态类型

需要静态类型才能工作,你可以做一些带有接口的忍者dynamics来绕过它的一部分,但你的问题没有提供这样的信息。

尝试将非泛型 IQueryable 强制转换为泛型(其中泛型属性是超类甚至只是对象(,例如:

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

这对我有用!