代码之家  ›  专栏  ›  技术社区  ›  Pablo Fernandez

如何使用实体框架为ASP.NET MVC排序相关对象

  •  0
  • Pablo Fernandez  · 技术社区  · 15 年前

    在实体框架(和linq-to-entities)中,有两个类,如blog和post,您如何获得按日期排序的日志。我是通过这种方式获得博客的:

    from blog in db.BlogSet.Include("Posts") select blog
    

    现在我不得不这样做:

    public class BlogAndPosts {
        public Blog Blog { get; set; }
        public IEnumerable<Post> Posts { get; set; }
    }
    
    from blog in db.BlogSet
    select new BlogAndPosts () {
        Blog = blog,
        Posts = blog.Posts.OrderByDescending(p => p.PublicationTime)
    }
    

    这是非常复杂和丑陋的。我创建blog posts类的原因是现在,因为我必须将blog和posts这两个变量传递给MVC,所以我需要一个视图模型。

    我甚至想试试这个黑客:

    from blog in db.BlogSet
    select new Blog(blog) {
        Posts = blog.Posts.OrderByDescending(p => p.PublicationTime)
    }
    

    但正确的方法是什么?实体框架不是MVC的发展方向吗?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Craig Stuntz    15 年前

    我通常创建一个完全不了解实体框架的表示模型类型,并将其投射到实体框架中。所以我会这样做:

    public class PostPresentation {
        public Guid Id { get; set; }
        public string Title { get; set; }
        public DateTime PostTime { get; set; }
        public string Body { get; set; }
    }
    
    public class BlogHomePresentation {
        public string BlogName { get; set; }
        public IEnumerable<Post> RecentPosts { get; set; }
    }
    
    from blog in db.BlogSet
    select new BlogHomePresentation 
    {
        BlogName = blog.name,
        RecentPosts = (from p in blog.Posts
                       order by p.PublicationTime desc
                       select new PostPresentation 
                       {
                           Id = p.Id,
                           Title = p.Title,
                           PostTime = p.PublicationTime,
                           Body = p.Body
                       }).Take(10)
    }
    

    这看起来有很多工作吗?考虑优点:

    1. 您的演示文稿是 完全地 对你的坚持一无所知。不是“无知的”,就像必须拥有所有的属性一样 public virtual ,但是 完全地 无知。
    2. 现在可以在设计数据库模式之前设计表示。你不需要事先做那么多的工作就可以得到客户的批准。
    3. 演示模型可以根据页面的需要进行设计。您不必担心急于加载或懒惰加载;您只需编写模型来适应页面。如果您需要更改页面或实体模型,可以在不影响另一个的情况下更改其中一个。
    4. 简单类型的模型绑定更容易。您将不需要具有此设计的自定义模型绑定器。
        2
  •  0
  •   Claus Trojahn    14 年前

    我还建议使用视图模型。当应用程序增长时,特定视图上可能会有更多内容,例如:

    public class PostDetailResult {
        public Post<Post> Post { get; set; }
        public IList<Post> RecentPosts { get; set; }
        public IList<Post> RelatedPosts { get; set; }
        public IList<Post> MostRated { get; set; }      
    }
    

    您可以像存储库一样在控制器和数据抽象之间添加另一层,因为您的BL应该决定什么是“mostrated”文章。如果在多个视图上使用“mostrated”日志,则不希望在多个控制器中写入相同的查询。对于存储库,控制器代码可能如下所示:

    var result = new PostDetailResult { 
        Post = repo.GetPost(id),
        RecentPosts = repo.GetRecentPosts(),
        RelatedPosts = repo.GetRelatedPosts(id)
    };
    

    希望,这有帮助。