【问题标题】:C# difference between linq select vs lambda selectC# linq 选择与 lambda 选择之间的区别
【发布时间】:2017-12-26 03:24:42
【问题描述】:

我有这个使用 EF db 上下文的测试查询。

Func<Item, ItemDto> qry = x => new ItemDto() {
  Id = x.Id,
  Name = x.Name
};
List<ItemDto> test1 = db.Items.Select(qry).ToList(); // works
List<ItemDto> test2 = (from item in db.Items select qry).ToList(); // run-time error

我的运行时错误

Cannot implicitly convert type 'System.Collections.Generic.List<System.Func<Progam.Item, Progam.ItemDto>>' to 'System.Collections.Generic.List<Progam.ItemDto>'

首先我不关注错误,而是想知道 Lambda-way Select 和 Linq-way Select Reference to NikolaiDante's answer 之间的区别。

谢谢!

*编辑

假设目标实际上是拥有类似的东西

Func<Item, ItemDto> qry = x => new ItemDto() {
      Id = x.Id,
      ItemCode = x.ItemCode
    };

var qry1 = (from p in db.Sales
            select new SaleDto() { 
                TranNo = p.TranNo
                , ExtItem = (from p1 in db.Items.Where(p2 => p2.ProductCode == p.ItemCode) 
                            select qry).FirstOrDefault()
}).ToList();

var qry2 = (from p in db.Returns
            select new ReturnDto() { 
                TranNo = p.TranNo
                , ExtItem = (from p1 in db.Items.Where(p2 => p2.ProductCode == p.ItemCode) 
                             select qry).FirstOrDefault()
}).ToList();

这可行吗?我确定我在这里做错了什么,可能有更好的模式来解决这个问题?

注意:我在这里也尝试做的是一次性查询,并避免在查询后使用foreach

【问题讨论】:

  • 不是运行时错误。 select qry -> select qry(item)
  • @PetSerAl 抱歉,您能进一步解释一下吗?

标签: c# linq


【解决方案1】:

select 查询运算符接受一个表达式,而不是一个 lambda。

因此,您的代码会生成一个 lambda 列表。

【讨论】:

  • 你的意思是我应该使用 Expression
【解决方案2】:

一般来说,它们都属于LINQ 框架,并且它们的性能是相同的,因为编译器会在程序集生成时将任何查询语法转换为方法语法(尽管它可能会为复杂的查询选择稍微不同的解释) .

欲了解更多信息,请阅读this

在某些情况下,lambda 可以用于匿名方法并且不会像 LINQ 那样受到威胁,例如 lambda expressions

编辑 - 问题更新

var qry2 = (from p in db.Returns
            select new ReturnDto()
            { 
                TranNo  = p.TranNo,
                ExtItem = (from p1 in db.Items.Where(p2 => p2.ProductCode == p.ItemCode)
                           select new ItemDto()
                           {
                               Id = p1.Id,
                               ItemCode = p1.ItemCode
                           })
                           .FirstOrDefault()
            })
            .ToList();

或者,根据您的 lambda 表达式:

var qry2 = (from p in db.Returns
            select new ReturnDto()
            { 
                TranNo  = p.TranNo,
                ExtItem = (from p1 in db.Items.Where(p2 => p2.ProductCode == p.ItemCode)
                           select qty(p1)).FirstOrDefault()
            })
            .ToList();

【讨论】:

  • 对,我做了一些编辑,但仍在尝试查看是否有可能使“选择”可重复用于其他查询。
  • 由于您的 qry 是一个表达式(不是 lambda),因此您应该按照 PetSerAl 的建议将其应用于 select qry(item) 之类的内容。
  • 所以基本上简短的回答是不可行的,因为我试图包装“选择”不是吗?
  • 是的,不幸的是,您可以随心所欲地做,您必须以某种方式将目标项目引用到您的表达式中才能应用它:) 选择运算符想要一个表达式来评估。
  • 这对于选择查询运算符来说很可悲,尽管我仍然想知道为什么 .Select(qry) 有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
相关资源
最近更新 更多