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”
DbContext.set() 无法为实体创建 DbSet,因为此类型未包含在上下文的模型中