我在一些项目中一直使用linq2sql,但我认为是时候尝试EF了,因为它应该更强大,更好。有一些东西真的很烦人。 其中一个是将结果投射到列表中,这在l2sql中很好用,但在EF中却不行。
public class bo.Transaction
{
public long Id { get; set; }
public List<bo.Line> Lines { get; set; }
}
public class bo.Line
{
public int RowNo { get; set; }
public string Descripton{ get; set; }
public double Amount{ get; set; }
}
return from t in Db.Transaction.Include("Lines")
select new bo.Transaction {
Id = t.Id,
Lines = t.Lines.OrderBy(l => l.RowNo).ToList(),
};
ToList()调用失败,但是消息“ System.NotSupportedException:LINQ to Entities无法识别方法'List [bo.Line] ToListLine'方法,并且此方法无法转换为商店表达.. ”。
有什么方法可以解决这个问题吗?或者我只需要使用ienumerable而不是列表?
答案 0 :(得分:2)
return (from t in Db.Transaction.Include("Lines")
select new bo.Transaction {
Id = t.Id,
Lines = t.Lines.OrderBy(l => l.RowNo),
}).ToList();
Linq查询只是不支持list,所以我们在Enumeration结果上执行它。但它确实强制Query在那一刻正确执行。返回IEnumerable会延迟执行查询的时间。 (基本上直到你要访问数据的那一刻。)
答案 1 :(得分:0)
这是一个黑暗中的刺,但你的项目是否有对System.Core dll的引用?如果没有此引用,.ToList()扩展方法将不可用。
另外,正如Workshop Alex指出的那样,你的.ToList()调用位置错误。
答案 2 :(得分:0)
什么写了工作室亚历克斯是对的,但让我解释它背后的理论:
您可能知道,当您编写LINQ-to-Entities查询时,您正在编写将针对您的数据库执行的操作。为了以有效的方式完成该操作,而不是获取每个实体,针对给定标准对其进行测试,对结果进行排序以及此类操作,查询将被转换为SQL并针对您的数据库运行。
但是,事实上,您的查询接受任何有效的C#,并不意味着您可以编写的所有代码都具有SQL的转换。没有翻译的代码的显着例子是混合数据访问和实体类反射的查询,或者 - 就像你的情况一样 - 使用特殊的.NET数据类型的代码。这种查询通常可以分两步执行,一个针对数据库进行操作,另一个针对RAM中的实体进行操作。虽然这可能不像你想的那样高效和干净,但我个人不喜欢存储过程,我仍然觉得它比你可能采取的大多数其他方法要好得多,只要你的约束条件允许你做出选择。
修改强>
确实可以很容易地处理这个场景,以这种方式运行db上的部分查询和内存中的一部分:
Db.Transaction.Include("Lines").Select(t => new bo.Transaction { t.Id, Lines = t.Lines.OrderBy(l => l.RowNo) }).AsEnumerable().Select(t => new bo.Transacton { t.Id, Lines = t.Lines.ToList()});
AsEnumerable调用有助于确保对已经从数据库中提取的一组对象运行第二个Select,因此不再存在将ToList转换为SQL的问题。