LINQ to Entities无法识别方法'System.Linq.IQueryable'

7
当我尝试在子查询中调用我的代码库时,出现了以下错误。
 IGrpTextRepository rep = new GrpTextRepository();

        var query = new DetailViewModel
        {
            ViewDet = (from gh in _db.Grp
                       select new MultiDetailViewModel
                       {
                           Header = gh,
                           Txts = rep.FindAllLangTxtById(gh.GrpID)

                       }).ToList(),
            Lang = _db.Language.ToList(),

        };

我的界面是

 public interface IGrpTextRepository
{
    IQueryable<GrpText> FindAllLangTxtById(int GrpID);
}

public class GrpTextRepository : IGrpTextRepository
{
    DBEntities db = new DBEntities();

    public IQueryable<GrpText> FindAllLangTxtById(int GrpID)
    {
        return (from lang in db.Language
               join gtxts in db.GrpText on lang.LangID equals gtxts.LangID into jointxt
               from fintxt in jointxt.DefaultIfEmpty()
               where fintxt.GrpID == GrpID
               select fintxt);
    }


}

以下是完整的错误信息:
System.NotSupportedException:LINQ to Entities不认识方法'System.Linq.IQueryable`1[aaa.Models.GrpText] FindAllLangTxtById(Int32)',该方法无法转换为存储表达式。


希望我能简洁地解释一下... 你对IQueryable接口、延迟执行和表达式树已经了解多少了? - John Farrell
1个回答

14
简单的解决方案是在 select(...) 前添加 .ToList()。
  ViewDet = _db.Grp.ToList().Select(gh => new MultiDetailViewModel ...)

这样,最初的请求将会进入数据库,返回结果,然后您可以使用针对Linq to objects的选择语句来重新投影它们。

但是我必须问一下为什么组和文本之间没有FK关系,因此没有实体关联两者,使您只需访问gh.GrpText并懒加载(或使用.Include()贪婪加载)获取文本集合。

正如@Doguhan Uluca在评论中指出的那样,使用ToList()很危险,因为它会导致该表中的所有内容都被提取到内存中。您应该仅在非常小的集合上使用它。正确的方法是修复您的数据库设计以便您可以高效地查询它。


我已经在组和文本之间建立了一个外键。我想用左连接和我的语言表格创建一个子查询。我想要每个组文本在不同语言下的列表。如果某个特定语言没有翻译该组文本,我希望结果为null。 - Jean-Francois
7
我建议不要在数据库表上调用 .ToList() 方法,除非您想把整个表加载到内存中。 - Doguhan Uluca
@DoguhanUluca - 那么在这种情况下,调用.ToList()的替代方法是什么? - oonyalo
在这种情况下,正确的选择是我提出的 - 使用FK关系,以便可以惰性(或急切)加载文本。有时,如果您知道它是一个小表,则ToList()很好,但通常,正如@DoguhanUluca指出的那样,这是错误的做法。您还可以投影到匿名类型,因为这可以转换为仅返回数据库中某些列的SELECT,但您仍然必须在某个时候将其转换为非匿名类型,以便从方法返回它。 - Ian Mercer
最近我一直在创建视图,然后使用LINQ来避免过于复杂的LINQ语句,因为它们真的不太好用。任何需要像Distinct这样的.ToList()操作,还需要稍后在代码中进行动态LINQ操作的操作,我建议使用数据库视图。 - Doguhan Uluca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接