【问题标题】:How to get a related object sorted with Entity Framework for ASP.NET MVC如何使用 ASP.NET MVC 的实体框架对相关对象进行排序
【发布时间】:2009-08-12 06:20:42
【问题描述】:

在实体框架(和 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)
}

这是非常复杂和丑陋的。我创建一个 BlogPosts 类的原因是,由于我必须将两个变量 Blog 和 Posts 传递给 MVC,我需要一个视图模型。

我什至很想试试这个技巧:

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

但是正确的方法是什么? Entity Framework 不适合 MVC 吗?

【问题讨论】:

    标签: asp.net-mvc entity-framework linq-to-entities


    【解决方案1】:

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

    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. 简单类型的模型绑定更容易。这种设计不需要自定义模型绑定器。

    【讨论】:

    • 只是为了记录,我认为这样做没有意义,除了解决实体框架。使用任何其他 ORM 我不会提取相关对象并将它们放在一个类中;不过,我会放入一个完全独立的数据类。无论如何,它有效,所以我接受它。
    【解决方案2】:

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

    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)
    };
    

    希望,这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多