C# 在IQueryable中执行函数

C# 在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之后,它可以

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

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之后要有更多的过滤器