LINQ On DbContext.Set()

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LINQ On DbContext.Set()相关的知识,希望对你有一定的参考价值。

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

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

但后来我无法执行其他LINQ,如Any()Single()。为什么这样,我怎么能改变呢?

答案

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

...将返回给你Customer(包裹在IQueryable<Customer>)有CustomerId == 1

你甚至可以使用Find方法:

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

这将返回单个Customer实例。

另一答案

根据您的要求,不,如果要求改变,您可能能够解决它。如果在运行时将类型作为字符串获取,那么在编译代码之前,您如何相信可以对其进行编程?

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

另一答案

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

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

这对我有用!

以上是关于LINQ On DbContext.Set()的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”

如何在泛型类型中使用 linq 包含函数

我的linq查询只是拉动它需要的东西还是所有东西?

DbContext.set() 无法为实体创建 DbSet,因为此类型未包含在上下文的模型中

在构造函数中存储DbSet而不是调用DbContext.Set 适合各种用途

使用 DbContext Set<T>() 而不是在上下文中公开