LINQ On DbContext.Set()

问题描述 投票:1回答:3

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

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

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

c# linq entity-framework reflection
3个回答
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实例。


0
投票

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

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


0
投票

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

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

这对我有用!

© www.soinside.com 2019 - 2024. All rights reserved.