LINQ On DbContext.Set()

时间:2014-10-22 11:40:38

标签: c# linq entity-framework reflection

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

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

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

3 个答案:

答案 0 :(得分:6)

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实例。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

这对我有用!