【问题标题】:select anonymous delegate with linq使用 linq 选择匿名委托
【发布时间】:2014-04-14 16:13:09
【问题描述】:

我知道有办法做到这一点,但我一直在用头撞墙试图弄明白。这工作正常:

private GenericRecord CreateGeneric(GenericRecord g, Member m)
{
    g.Member = m;
    return g;
}

public IList<GenericRecord> ReportFromDatabase(DateTime startDate, DateTime endDate)
{
    List<GenericRecord> returnRecords = new List<GenericRecord>();

    returnRecords.AddRange(from r in pjRepository.Records
                           join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                           where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                           select CreateGeneric((GenericRecord)r, m));

    return returnRecords;
}

但我知道有一种方法可以不使用 CreateGeneric 函数。如何选择内联委托函数?

returnRecords.AddRange(from r in pjRepository.Records
                       join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                       where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                       select (delegate
                       {
                           GenericRecord g = (GenericRecord)r;
                           g.Member = m;
                           return g;
                       }));

这给了我这个例外:

The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.

编辑:又一次失败的尝试

returnRecords.AddRange((from r in pjRepository.Records
                        join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                        where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                        select new { r, m }).Select(x =>
                        {
                            GenericRecord g = (GenericRecord)x.r;
                            g.Member = x.m;
                            return g;
                        }));

这给了我:

带有语句体的 lambda 表达式不能转换为表达式树。

【问题讨论】:

    标签: c# linq delegates


    【解决方案1】:

    试试:

    returnRecords.AddRange((from r in pjRepository.Records
                                join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
                                where r.TransactionDate >= startDate && r.TransactionDate <= endDate
                                select new { r, m }).AsEnumerable().Select(x =>
                                {
                                    GenericRecord g = (GenericRecord)x.r;
                                    g.Member = x.m;
                                    return g;
                                }));
    

    关键的不同在于 AsEnumerable() 函数。这需要一个 IQueryable 并返回一个 IEnumerable,它在幕后强制 Linq 提供程序对表达式树进行评估。这可以防止 Linq 库尝试将第二个 Select 的 lambda 转换为表达式树的一部分(它说它不能);第二个 Select 将改为对通过评估 IQueryable 表达式树产生的实际内存集合执行其转换。由于您需要在语句结束之前评估查询(因此所有元素都可以添加到 returnRecords),因此应该没有显着的性能差异。

    【讨论】:

      【解决方案2】:
      Seem like this is what you are looking at:
      class Bila
          {
              public string Name;
              public List<string> Adresses;
          }
           var justNumbers = Enumerable.Range(0, 10);
      Func<int,List<string>> foo = delegate(int j)
          {
              List<string> lst = new List<string>();
              for (int kk = 0; kk < j; kk++)
              {
                  lst.Add("String_" + kk.ToString());
              }
              return lst;
          };
      var zilla3 = (from x in justNumbers
                    select new Bila
                    {
                        Name = "Name_" + x.ToString(),
                        Adresses = foo(x),
                    }).ToArray();
      

      【讨论】:

      • 提供一些描述。
      猜你喜欢
      • 2011-02-08
      • 1970-01-01
      • 2010-11-01
      • 2010-11-01
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多