我知道有一种方法可以做到这一点,但我一直在用头撞墙试图找出答案。这很好用:
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 表达式无法转换为表达式树。
尝试:
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),因此应该不会有显着的性能差异。
看起来这就是您正在看的:
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();