【问题标题】:Asp.net MVC error : LINQ to Entities does not recognizeAsp.net MVC 错误:LINQ to Entities 无法识别
【发布时间】:2011-12-23 15:10:42
【问题描述】:

我得到了错误:

LINQ to Entities 无法识别方法 'PagedList.IPagedList1[MvcMusicStore.Models.Album] ToPagedList[Album](System.Collections.Generic.IEnumerable1[MvcMusicStore.Models.Album], Int32, Int32)' 方法,并且该方法无法转换为存储表达式

对于我的以下控制器操作:

    public ActionResult Browse(string genre, int?page)
    {
        // Retrieve Genre and its Associated Albums from database
        int pageIndex = page ?? 1;
        var genreModel = storeDB.Genres.Where(g => g.Name == genre)
                                       .Select(g => new GenreAlbumView
                                       {
                                           ID = g.GenreId,
                                           Name = g.Name,
                                           Albums = g.Albums.ToPagedList(pageIndex, PageSize)
                                       }).SingleOrDefault();
        return View(genreModel);
    }

这个问题的原因和解决办法是什么?

【问题讨论】:

    标签: c# linq asp.net-mvc-3 pagination viewmodel


    【解决方案1】:

    首先运行您的通用模型查询:

    var genreModel = storeDB.Genres.Where(g => g.Name == genre).SingleOrDefault();
    

    然后运行您的选择。

    因为 lin2entity 的功能支持有限,无法转换你的功能:

    g.Albums.ToPagedList(pageIndex, PageSize)
    

    对于挪用的sql命令,实际上它并不能为其创建相关的表达式树,所以你应该先获取实体,然后选择你想要的方式。

    如果您应该在 DB 中进行这样的分页,请创建一个存储过程并使用它。

    【讨论】:

    • 谢谢兄弟,但我不确定将哪个答案标记为已接受:-)。两个答案都有效,我不知道哪个表现更好。
    • @Pankaj 希望这对你有帮助,如果两个答案对你掷硬币有同等价值:)
    • LOL...我将此标记为答案,因为它看起来更好。而且,我没有找到任何理由或情况应该使用更喜欢跳过并接管这种方法。
    【解决方案2】:

    问题是 ToPagedList 方法不是可以转换为 SQL 查询并在数据库中执行的东西。

    对于数据库服务器上的分页,您可以使用 Skip 和 Take 方法。

    尝试以下方法:

    var genreModel = storeDB.Genres.Where(g => g.Name == genre)
                                           .Select(g => new GenreAlbumView
                                           {
                                               ID = g.GenreId,
                                               Name = g.Name,
                                               Albums = g.Albums.Skip(PageSize * (PageIndex -1)).Take(PageSize)
                                           }).SingleOrDefault();
    

    当您使用可以转换为 sql 命令的 Skip/Take 时,分页将在数据库服务器上完成,但是当您第一次执行查询然后调用 ToPagedList 方法时,您会遇到性能损失。然后在内存中对已从数据库加载的所有专辑执行分页。

    这个原则与 Linq 所说的延迟执行有关。 您正在构建一个表达式树,它仅在您“执行”表达式树(使用例如 Single、ToList、First、Count 或类似方法)时才会在 SQL 中翻译,Sql 命令会在数据库服务器上生成并执行。

    因此,如果您先调用“ToList”,然后调用分页,您将从数据库中获取所有记录并将它们分页到内存中,这会慢很多。

    【讨论】:

    • 感谢伙伴触及更深层次的问题,让我明白为什么会这样。
    • 对不起,我将 Saeed 的答案标记为已接受,因为它看起来很干净,而且方法更好。但是,当人们喜欢或需要使用跳过/接管 Saeed 的方法时,您能帮我理解任何情况吗?
    猜你喜欢
    • 2014-11-16
    • 2013-06-04
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 2014-08-09
    相关资源
    最近更新 更多