【问题标题】:Trouble putting Statement Lambda inside a LINQ query将 Statement Lambda 放入 LINQ 查询时遇到问题
【发布时间】:2011-03-16 17:14:57
【问题描述】:

我正在尝试将一些内联工作作为 Statement Lambda 注入到 LINQ 查询 select 中,就像这样...

// NOTE: mcontext.Gettype() == System.Data.Linq.DataContext

// Okay - compiles, nothing unusual
var qPeople1 = from ME.tblPeople person in mcontext.tblPeoples
              select person;

// ERROR - see below compile Error - Can I retrofit this thing?
var qPeople2 = from ME.tblPeople person in mcontext.tblPeoples
               select (() => { 
                   return person; 
               })();

错误:

错误 2 方法名称 预期 file.cs 166 27 MigrationCore

...不过,我同样很高兴看到 Expression Lambda 首先内联工作。

注意:我知道代码示例的工作是多余的,但我正在寻找基本概念。如果可行,我将对其进行扩展。

【问题讨论】:

  • 错误告诉你编译器把它看作是一个函数调用,如果你去掉尾括号会发生什么?
  • @Kjartan:删除括号会出现错误:The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.

标签: c# .net linq lambda datacontext


【解决方案1】:

查询语法需要方法引用 - 它不接受 lambda,在您的第二个示例中,您给它一个 ME.tblPeople 实例。

但是,如果您使用扩展方法语法,您可以轻松实现:

int i = 0;
var qPeople3 = (from ME.tblPeople person in mcontext.tblPeoples
                select person).Select(person => { i += 1; return person; });

(我添加了递增整数作为示例,但请注意,在您枚举 qPeople3 之前,它实际上不会从零开始变化。)

附录

这仅适用于 LINQ to Objects。要将其与 LINQ to SQL 查询一起使用,需要在调用 Select() 之前调用 AsEnumerable()

备注

对于这个例子,你实际上并不需要 from-in-select 构造,下面的 sn-ps 是 (AFAICT) 相同的,但我把它留在上面是为了与前面的例子相似并说明它是有效的。第二个 sn-p 将两个语句分成不同的行,结果也相同。

int i = 0;
var qPeople4 = mcontext.tblPeoples.Select<ME.tblPeople,ME.tblPeople>(person => { i += 1; return person; });
int i = 0;
var qPeople1 = from ME.tblPeople person in mcontext.tblPeoples
               select person;
var qPeople5 = qPeople1.Select(person => { i += 1; return person; });

【讨论】:

  • 您的 qPeople3 语句给了我 CSC 3.5 编译错误:A lambda expression with a statement body cannot be converted to an expression tree
  • 实际上没有一个编译 - 他们都给出了上述编译错误。
  • 现在我意识到您可能没有看到源代码中的数据上下文。需要AsEnumerable,正如这里回答的stackoverflow.com/questions/3261037/3261819#3261819
  • 啊,我明白了。我只用 LINQ to Objects 测试了它,而不是 LINQ to SQL。我的错。 AsEnumerable() 调用将其从 IQueryable 更改为 IEnumerable。如果人们不阅读 cmets,我会在我的答案中添加一个附录(我赞成 dahlbyk 的答案,因为他注意到了我的遗漏)。
【解决方案2】:

有两种 lambda 表达式:匿名委托和表达式树。前一种由 LINQ to Objects 使用,并允许任何有效的匿名方法体。后一种类型由 LINQ to SQL 使用,并要求其主体是单个表达式。然后将该表达式传递到 L2SQL 运行时,并在发送到服务器的 SQL 中进行操作。

要执行内联工作,您需要使用两个步骤:1) 使用有效的 select 表达式获取 SQL 数据,然后 2) 使用 LINQ to Objects 将该数据作为 IEnumerable 操作以完成内联工作.这可能看起来像这样:

var qPeople1 = from ME.tblPeople person in mcontext.tblPeoples
              select person;

var i = 0;
var qPeople2 = qPeople1.AsEnumerable().Select(person => {
                   i += 1;
                   return person; 
               });

【讨论】:

  • 这说明了我的情况。我很高兴您看到了用于 SQL 的 DataContext。我运行了代码,效果很好。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多