Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq 如何";让我们;用lambda表达?_Linq_Entity Framework_C# 4.0_Lambda_Let - Fatal编程技术网

Linq 如何";让我们;用lambda表达?

Linq 如何";让我们;用lambda表达?,linq,entity-framework,c#-4.0,lambda,let,Linq,Entity Framework,C# 4.0,Lambda,Let,如何使用lambda表达式将此linq查询重写为上的实体? 我想在lambda表达式中使用let关键字或等效项 var results = from store in Stores let AveragePrice = store.Sales.Average(s => s.Price) where AveragePrice < 500 && AveragePrice > 250 它将为每个项目计算Ave

如何使用lambda表达式将此linq查询重写为上的实体?
我想在lambda表达式中使用let关键字或等效项

var results = from store in Stores
              let AveragePrice =  store.Sales.Average(s => s.Price)
              where AveragePrice < 500 && AveragePrice > 250

它将为每个项目计算AveragePrice,而在我提到的查询样式中,让表达式阻止多次计算average。

因此,您可以使用扩展方法语法,这将比您当前使用的多涉及一个lambda表达式。没有
let
,您只需使用多行lambda并声明一个变量:

var results = Stores.Where(store => 
{
    var averagePrice = store.Sales.Average(s => s.Price);
    return averagePrice > 250 && averagePrice < 500;
});
var results=Stores.Where(store=>
{
var averagePrice=store.Sales.Average(s=>s.Price);
返回averagePrice>250&&averagePrice<500;
});
请注意,我更改了平均价格比较,因为您永远不会返回任何结果(大于500,小于250)

另一种选择是

var results = Stores.Select(store => new { Store = store, AveragePrice = store.Sales.Average(s => s.Price})
    .Where(x => x.AveragePrice > 250 && x.AveragePrice < 500)
    .Select(x => x.Store);
var results=Stores.Select(store=>new{store=store,AveragePrice=store.Sales.Average(s=>s.Price})
其中(x=>x.AveragePrice>250&&x.AveragePrice<500)
.选择(x=>x.Store);

基本上,您需要使用Select和匿名类型将平均值添加到对象中,然后是语句的其余部分

未测试,但应如下所示:

Stores.Select(
x => new { averagePrice = x.Sales.Average(s => s.Price), store = x})
.Where(y => y.averagePrice > 500 && y.averagePrice < 250)
.Select(x => x.store);
var results = Stores
    .Where(store => store.Sales.Average(s => s.Price)
        .Pipe(averagePrice => averagePrice < 500 && averagePrice > 250));
Stores.Select(
x=>new{averagePrice=x.Sales.Average(s=>s.Price),store=x})
其中(y=>y.averagePrice>500&&y.averagePrice<250)
.选择(x=>x.store);
警告,请小心使用这些构造。使用let会为集合中的每个对象创建一个新的匿名类型,这会在大型集合中消耗大量内存

详情请看这里:

另一个选项是定义此扩展方法:

public static class Functional
{
    public static TResult Pipe<T, TResult>(this T value, Func<T, TResult> func)
    {
        return func(value);
    }
}    
公共静态类函数
{
公共静态TResult管道(此T值,Func Func)
{
返回func(值);
}
}    
然后按如下方式编写查询:

Stores.Select(
x => new { averagePrice = x.Sales.Average(s => s.Price), store = x})
.Where(y => y.averagePrice > 500 && y.averagePrice < 250)
.Select(x => x.store);
var results = Stores
    .Where(store => store.Sales.Average(s => s.Price)
        .Pipe(averagePrice => averagePrice < 500 && averagePrice > 250));
var结果=存储
.Where(store=>store.Sales.Average(s=>s.Price)
.Pipe(averagePrice=>averagePrice<500&&averagePrice>250);

我们可以通过内联输出声明避免在所有其他答案中使用lambda的开销:

公共静态类函数
{
公共静态T分配(此T o,输出T结果)=>
结果=o;
}
这样称呼它

var结果=存储
.Where(store=>store.Sales
.平均(s=>s.价格)
.分配(外部var averagePrice)<500&&averagePrice>250);

可能重复@Eranga:I这个问题,Marc为每个项目选择了animalName.Length。在这里,我不想为每个项目计算所有项目的平均值。@Reza:平均值仅为每个存储对象计算一次,与您的查询完全一样……错误:带有语句体的lambda表达式无法转换为表达式树。您的第一个报价仅在内存上有效,无法在像EF这样的LINQ提供程序中使用。带有语句体的lambda表达式无法转换为表达式树。@amkh:我几乎可以肯定在问题的第一个版本中没有提到EF。或者至少Jay和我都没有注意到…@Reza:平均值仅每分钟计算一次存储对象,就像在查询中一样…@Reza不,我不希望它一定会提高EF查询性能。答案只是关于如何使用扩展方法语法执行类似于的操作。为什么不坚持使用查询语法呢?如果这些是LINQ to Entities查询或simila,它不会消耗任何内存r、 事实上,只有linq to对象才是。THX这应该是公认的答案,因为它允许您在不同的“子句”中使用变量。