C# 在IQueryable中执行函数
使用Linq,很容易执行一个函数来投影IEnumerableC# 在IQueryable中执行函数,c#,entity-framework,iqueryable,func,C#,Entity Framework,Iqueryable,Func,使用Linq,很容易执行一个函数来投影IEnumerable var orders = new List<Order>(); orders.Where(x => x.Id > 50).Select(x => new SomethingElse(x.Name)); 是否存在,或者是否有可能为上述工作创造一种方式? 我知道它不起作用,因为它无法将函数转换成SQL可以理解的东西,但是,如果有一个名为“Execute”的扩展方法,在执行之前和之后的所有linq之后,它可以
var orders = new List<Order>();
orders.Where(x => x.Id > 50).Select(x => new SomethingElse(x.Name));
是否存在,或者是否有可能为上述工作创造一种方式?
我知道它不起作用,因为它无法将函数转换成SQL可以理解的东西,但是,如果有一个名为“Execute”的扩展方法,在执行之前和之后的所有linq之后,它可以在内存中执行,那么它会起作用吗
数据库只会拉到>50和前10名,只有在之后才会拉到
var db = new Order();
db.MyEntities.Where(x => x.Id > 50).Execute(x => new SomethingElse(x.Name)).Take(10);
澄清一下:要求是即使在Sleect()之后也要保持它的可用性。否,因为您需要将所有数据运回数据库才能完成最后一部分 通常,您有一个额外的
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));
请注意,您可能会遇到,它确实会从
IEnumerable
生成IQueryable
——但它并不能满足您的需要。如果源不是真正可查询的,它将“伪造”它,但不会将它连接回数据库,这是您所追求的。否,因为您需要将所有数据发送回数据库才能完成最后一部分
通常,您有一个额外的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));
请注意,您可能会遇到,它确实会从
IEnumerable
生成IQueryable
——但它并不能满足您的需要。如果源不是真正可查询的,它将“伪造”它,但不会将其连接回数据库,这就是您所追求的。是的,当然可以,只需调用如下所示的numerable()函数即可:
var db = new Order();
db.MyEntities.Where(x => x.Id > 50)
.Take(10)
.AsEnumerable()
.Execute(x => new SomethingElse(x.Name));
在Linq to中,调用函数(如AsEnumerable(),FirstOrDefault())的实体将执行查询。因此,我们在该函数之后所做的工作意味着我们处理的是对象,而不是数据库。是的,当然也可以只调用如下所示的numerable()函数:
var db = new Order();
db.MyEntities.Where(x => x.Id > 50)
.Take(10)
.AsEnumerable()
.Execute(x => new SomethingElse(x.Name));
在Linq to中,调用函数(如AsEnumerable(),FirstOrDefault())的实体将执行查询。因此,我们在函数之后所做的工作意味着我们处理的是对象,而不是数据库。是的,这是可能的,但您必须稍微扭转局面:
var db = new Order();
db.MyEntities.Where(x => x.Id > 50)
.Take(10)
.AsEnumerable() // This will fetch data from the DB
.Select(x => new SomethingElse(x.Name)); // Here, data is already fetched
这里的区别在于执行的不同:Where()
、Select()
、Take()
,以及一些其他操作被延迟,即在计算整个表达式之前不调用,从而允许将整个表达式有效地映射到适当的SQL语句
另一方面,AsEnumerable()
是一个非延迟运算符。它允许将输入序列转换为正常的IEnumerable
序列,从而允许调用标准查询运算符方法
与其他一些操作符(如
ToList()
、First()
)等)一起,这实际上会导致在应用查询之前执行查询的第一部分。在此上下文中,这意味着查询的第一部分将转换为SQL并运行。结果将传递给下一个运算符—您的Select()
语句—然后您可以按预期使用该语句。是的,这是可能的,但您必须稍微扭转局面:
var db = new Order();
db.MyEntities.Where(x => x.Id > 50)
.Take(10)
.AsEnumerable() // This will fetch data from the DB
.Select(x => new SomethingElse(x.Name)); // Here, data is already fetched
这里的区别在于执行的不同:Where()
、Select()
、Take()
,以及一些其他操作被延迟,即在计算整个表达式之前不调用,从而允许将整个表达式有效地映射到适当的SQL语句
另一方面,AsEnumerable()
是一个非延迟运算符。它允许将输入序列转换为正常的IEnumerable
序列,从而允许调用标准查询运算符方法
与其他一些操作符(如ToList()
、First()
)等)一起,这实际上会导致在应用查询之前执行查询的第一部分。在此上下文中,这意味着查询的第一部分将转换为SQL并运行。结果将传递给下一个操作符—您的Select()
语句—然后您可以按预期使用它。您可以构建“WHERE”:
expressionexpresionfinal=p=>p.Active;
if(mydate.HasValue)
{
表达式expresionDate=p=>(EntityFunctions.TruncateTime(c.CreatedDate)(codeProduct==c.codProduct);
expresionFinal=PredicateBuilder.And(expresionFinal,expresionCode);
}
IQueryable query=dbSet;
query=query.Where(expresionFinal);
您可以构建“WHERE”:
expressionexpresionfinal=p=>p.Active;
if(mydate.HasValue)
{
表达式expresionDate=p=>(EntityFunctions.TruncateTime(c.CreatedDate)(codeProduct==c.codProduct);
expresionFinal=PredicateBuilder.And(expresionFinal,expresionCode);
}
IQueryable query=dbSet;
query=query.Where(expresionFinal);
我们的想法是,即使在选择之后,也要将其保持为IQueryable。因此,要使其按照定义的顺序工作。因此,在.Select()之后要有更多的过滤器@哈赛尔:我的观点是,不,你不能那样做……但是如果你想做的事情是可行的,通常有办法避免它成为一个问题。如果你需要数据库使用只能在本地获得的信息,没有干净有效的方法。我担心:(我们的想法是,即使在Select.So之后,也要将其保持为IQueryable。因此,要使其按照定义的顺序工作。因此,在.Select()@hatcyl:和m之后要有更多的过滤器