2010-08-20 159 views
6

当我尝试在Sub Select中调用我的存储库时,出现此错误。LINQ to Entities无法识别方法'System.Linq.IQueryable

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实体无法识别方法“System.Linq.IQueryable`1 [aaa.Models .GrpText] FindAllLangTxtById(Int32)'方法,并且此方法不能转换为存储表达式。

+0

希望我能够简洁地解释一下......您对IQueryable接口,延迟执行和表达式树已经了解多少? – jfar 2010-08-20 23:04:21

回答

13

简单的解决方案是在选择(...)之前添加一个.ToList()。

ViewDet = _db.Grp.ToList().Select(gh => new MultiDetailViewModel ...) 

这样的初始请求将进入数据库,回来的结果,然后你可以使用针对LINQ的select语句的对象重新投影他们。

但我必须问为什么组和文本之间没有FK关系,因此两者之间的实体关联允许您只访问gh.GrpText并获得延迟加载的文本集合(或急切加载使用.Include())。

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

+0

I在组和文本之间已经有FK。 。我想用我的语言表进行一个左连接的子查询。我想要不同语言的每个组文本的列表。如果组文本不是针对特定语言的转换,我希望结果为空。 – 2010-08-21 17:06:54

+7

我建议不要在数据库表上调用.ToList(),除非你想在内存中加载整个表。 – 2013-02-28 16:04:41

+0

@DoguhanUluca - 那么在这种情况下调用.ToList()的替代方法是什么? – oonyalo 2014-04-17 18:00:55

相关问题