在IQueryable中执行函数

hat*_*cyl 0 c# entity-framework iqueryable func

使用Linq,很容易执行一个函数来投影IEnumerable.

var orders = new List<Order>();
orders.Where(x => x.Id > 50).Select(x => new SomethingElse(x.Name));
Run Code Online (Sandbox Code Playgroud)

使用EntityFramework和IQueryable,这是不可能的.而是在运行时获得不受支持的异常,因为您在Select中没有函数.

不起作用:

var db = new Order();
db.MyEntities.Where(x => x.Id > 50).Select(x => new SomethingElse(x.Name)).Take(10);
Run Code Online (Sandbox Code Playgroud)

是否存在,或者是否有可能为上述工作创造一种方式?

我理解它不起作用,因为它无法将函数转换为SQL可以理解的东西,但是,如果有一个名为'Execute'的扩展方法可以在执行所有linq之前和之后在内存中执行,那会起作用吗?

数据库将仅拉动> 50并且仅在TOP 10之后

var db = new Order();
db.MyEntities.Where(x => x.Id > 50).Execute(x => new SomethingElse(x.Name)).Take(10);
Run Code Online (Sandbox Code Playgroud)

澄清:要求是即使在Sleect()之后仍然保持IQueryable

Jon*_*eet 6

不,因为您需要将所有数据发送回数据库以执行最终部分.

通常,您只需要额外Select的信息即可获得查询中所需的信息(如果您需要多个属性,则使用匿名类型),然后在本地执行所有其他操作:

var query = db.MyEntities
              .Where(x => x.Id > 50)
              .Select(x => x.Name) // All we need - keep the query cheap
              .Take(10)
              .AsEnumerable()
              .Select(x => new SomethingElse(x));
Run Code Online (Sandbox Code Playgroud)

请注意,您可能遇到过Queryable.AsQueryable,它产生IQueryable<T>一个IEnumerable<T>- 但它不会做你想要的.如果源不是真正可查询的,它将"伪造"它但不将它连接回数据库,这就是你所追求的.