【问题标题】:PetaPoco and Many-to-One, One-to-Many and Many-to-Many relationsPetaPoco 和多对一、一对多和多对多关系
【发布时间】:2011-08-29 13:57:33
【问题描述】:

PetaPoco 以实验形式引入了 Multi-POCO 查询(目前)。正如 their blog post 所建议的那样,当我们每行加载多个 POCO 时,它提供的代码看起来不错,并且所有的都是 一对一 关系,只要它们不重复记录。

当至少一侧是 many 关系时会发生什么?实际上示例代码是多对一关系数据。

示例代码显然是多对一关系。我没有测试任何 PetaPoco 代码,但博文中提供的代码有什么作用?每个Article 是否都有自己的User 对象实例,即使有些可能是同一个用户,或者他们共享同一个用户对象实例?

那么其他 Many 关系类型呢?它们是如何工作的?

【问题讨论】:

    标签: relational-database petapoco


    【解决方案1】:

    通常我自己映射这些一对多查询,如下例所示。

    [TableName("Blogs"), PrimaryKey("BlogId")]
    public class Blog {
        public int BlogId {get;set;}
        public string Title {get;set;}
    
        [Ignore]
        public IList<Post> Posts {get;set;}
    }
    
    [TableName("Posts"), PrimaryKey("PostId")]
    public class Post {
        public int PostId {get;set;}
        public int BlogId {get;set;}
        public string Subject {get;set;}
        public string Content {get;set;}
    }
    
    public class FlatBlogPost {
        public int BlogId {get;set;}
        public string Title {get;set;}
        public int PostId {get;set;}
        public string Subject {get;set;}
        public string Content {get;set;}
    }
    

    有两种方法可以显示一个博客的帖子列表,或者无需太多工作即可显示所有博客。

    1.两个查询 -

    var Blog = Db.Query<Blog>(1);  
    var Posts = Db.Query<Post>("where BlogId = @0", 1);
    

    2.一次查询 =

    var flat = Db.Query<FlatBlogPost>("select b.blogid, b.title, p.postid, p.subject, 
               p.content from blogs b inner join posts p on b.blogid = p.blogid where
               b.blogid = @0", 1);
    
    var blog = flat
        .GroupBy(x=> new { x.BlogId, x.Title })
        .Select(x=> new Blog {
            BlogId = x.Key.BlogId,
            Title = x.Key.Title,
            Posts = x.Select(y=> new Post{
                        PostId = y.PostId,
                        BlogId = x.Key.BlogId,
                        Subject = y.Subject,
                        Content = y.Content
                    }).ToList()
        });
    

    但通常在第 2 位中,我会直接从 FlatBlogPost 对象映射到我需要显示数据的视图模型。

    更新
    查看这些扩展 PetaPoco 以支持基本的一对多和多对一查询的助手。 schotime.net/blog/index.php/2011/08/21/petapoco-one-to-many-and-many-to-one/ https://schotime.wordpress.com/2011/08/21/petapoco-one-to-many-and-many-to-one/

    【讨论】:

    • 这不是很好。这是一种骇人听闻的解决方法(我不喜欢完整的 ORM 的原因之一,因为您最终会修改代码以使 ti 工作并使其快速工作(呃))。现在支持多结果集不会太难吧?这绝对比自动拆分列少。 Dapper 支持多个结果集为什么 PetaPoco 不能这样做。您不需要平面类,并且您也可以将更少的数据从数据库传输到中间层。
    • 但是您的答案仍然值得 +1,因为它是一个可能的解决方案。
    【解决方案2】:

    我个人认为您无法避免另一个数据库调用来获取 cmets。您可以通过使用 IN 子句获取 10 篇文章的所有 cmets 列表(按照文章的存储顺序),然​​后循环遍历它们,将它们添加到每个 article.cmets 中,并且 comment.articleid 发生变化。我可以看到在单个 sql 调用中获取此信息的唯一方法是使用连接,但随后您将获得每个评论的重复文章详细信息,所以也许这不是 petapoco 的问题,只是其中之一'永远不会完美

    【讨论】:

    【解决方案3】:

    我的 Petapoco 的“一对多”食谱如下。文档对我来说不够清楚。在 Linqpad 中创建一个 db 连接,它将显示您可以添加到生成的 Petapoco poco 类的所有导航属性。在 Linqpad 中执行相同的 SQL,以确保它获得您期望的数据。

    // subclass the generated Parent table pocos, add navigation prop for children
    [ResultColumn]  public List<DecoratedChild> Child { get; set; } 
    
    // subclass the generated Child table pocos,  add navigation prop for parent  
    [ResultColumn]  public DecoratedParent Parent { get; set; }      
    
    // to get children with parent info
    List<DecoratedChild> children = db.Fetch<DecoratedChild, DecoratedParent>(SELECT child.*, parent.* from ...)     
    
    // to get children with parent info, using PetapocoRelationExtensions
    List<Child> children = db.FetchManyToOne<Child, Parent>(child => child.ID, "select child.*, parent.* from ...
    
    // to get parents with children info, using PetapocoRelationExtensions              
    List<Parent> parents = db.FetchOneToMany<Parent, Child>(par => par.ID, child => child.ID != int.MinValue, "select parent.*, child.* from ...    
    

    SQL 选择顺序很重要,与获取类型列表中的相同!!! 导航道具将有父或子数据... 有 3 个级别的调用将是这样的:

    List<DecoratedGrandChild> grandChildColl = db.Fetch<DecoratedGrandChild, DecoratedChild, DecoratedParent>(SELECT grandch.* , child.*, parent.* from ...)
    

    【讨论】:

      猜你喜欢
      • 2020-07-12
      • 2015-07-05
      • 2015-02-05
      • 1970-01-01
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      相关资源
      最近更新 更多