PetaPoco和多对一,一对多和多对多的关系

时间:2011-05-20 11:00:26

标签: relational-database petapoco

PetaPoco 以实验形式推出了多POCO查询(暂时)。正如 their blog post 建议并且它提供的代码看起来不错,并且当我们每行加载多个POCO时,所有这些都在一对一关系中不要重复记录。

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

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

那么其他许多关系类型呢?他们如何工作?

3 个答案:

答案 0 :(得分:7)

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

[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.One query =

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对象映射到我需要显示数据的viewmodel。

<强>更新
查看扩展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/

答案 1 :(得分:1)

Petapoco的“一对多”食谱如下。文档对我来说不够清楚。在Linqpad中创建数据库连接,它将显示您可以添加到生成的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 ...)

答案 2 :(得分:0)

我个人认为你不能避免另一个数据库调用来获取评论。您可以使用IN子句获取10篇文章的所有注释列表(以相同的顺序存储文章),并循环浏览它们,随着时间的推移将它们添加到每个article.com中并且comments.articleid会发生变化。我在单个sql调用中看到获取此信息的唯一方法是使用连接,但是你会得到每个注释的重复文章详细信息,所以也许这不是petapoco的问题,只是其中一个永远不会是完美的