ServiceStack / ORM精简版 - 外键关系(ServiceStack / ORM Li

2019-08-08 04:03发布

我有以下POCO:

[Alias("Posts")]
public class Post : IReturn<Post>
{
    [AutoIncrement]
    [PrimaryKey]
    public int PostId { get; set; }
    public DateTime CreatedDate { get; set; }
    [StringLength(50)]
    public string CreatedBy { get; set; }
    [StringLength(75)]
    public string Title { get; set; }
    public string Body { get; set; }
    public int UpVote { get; set; }
    public int DownVote { get; set; }
    public bool IsPublished { get; set; }

    public List<Comment> Comments { get; set; }
    public List<Tag> Tags { get; set; }
}

它有一个我的FK CommentTag实体。 所以我想回到那些从我的服务我的反应,但它说'Invalid Column name 'Comments'''Invalid Column name 'Tags'' 。 如何查看其评论和标签附在我的帖子,与ORM精简版? 在EF我会简单地使用包括对延迟加载我相关表格信息,什么等价?

编辑

在回答问题的答案,我已经做到了这一点:

public class PostFull
{
    public Post Post { get; set; }
    public List<Comment> Comments { get; set; }
    public List<Tag> Tags { get; set; }
}

然后在我的服务,我回到这一点,我的实体PostTag交叉路口实体我的PostTag实体是A M:M关系:

var posts = Db.Select<Post>().ToList();
var fullPosts = new List<PostFull>();

posts.ForEach(delegate(Post post)
{
    var postTags = Db.Select<PostTag>(x => x.Where(y => y.PostId == 
    post.PostId)).ToList();

    fullPosts.Add(new PostFull()
    {
        Post = post,
        Tags = Db.Select<Tag>(x => x.Where(y => postTags.Select(z => 
                   z.TagId).Contains(y.TagId))).ToList(),
        Comments = Db.Select<Comment>(x => x.Where(y => y.PostId == 
                       post.PostId)).ToList()
    });
});

return fullPosts;

不知道是否它是一个很好的设计模式或不?

编辑2

这里是我的实体:

[Alias("Tags")]
public class Tag
{
    [AutoIncrement]
    [PrimaryKey]
    public int TagId { get; set; }

    [StringLength(50)]
    public string Name { get; set; }
}

[Alias("Posts")]
public class Post
{
    [AutoIncrement]
    [PrimaryKey]
    public int PostId { get; set; }
    public DateTime CreatedDate { get; set; }
    [StringLength(50)]
    public string CreatedBy { get; set; }
    [StringLength(75)]
    public string Title { get; set; }
    public string Body { get; set; }
}

[Alias("PostTags")]
public class PostTag
{
    [AutoIncrement]
    [PrimaryKey]
    public int PostTagId { get; set; }

    [References(typeof(Post))]
    public int PostId { get; set; }

    [References(typeof(Tag))]
    public int TagId { get; set; }
}

Answer 1:

在OrmLite表是严格意义上的1:1映射与底层分贝表。

这就意味着所有的复杂类型属性blobbed到一个数据库文本字段属性名称,你希望在这里做他们从来没有使用过自动映射到子女的关系。

下面是一个早期的答案,显示了如何你可以映射很多与OrmLite许多关系 。

尽量避免N + 1个查询,请记住,每一个呼叫Db.x是一个远程数据库查询,以便您应尽量避免在循环中的任何数据库调用。

许多检索到的帖子很多表查询

您可以使用OrmLite的支持JOIN的构造类型化查询,你会在正常的SQL由许多查询到许多表并找到指定标签的帖子:

Create and Populate Posts with Test Data
db.CreateTable<Post>();
db.CreateTable<Tag>();
db.CreateTable<PostTag>();

var post1Id = db.Insert(new Post { 
    CreatedBy = "gistlyn", Title = "Post 1", Body = "Body 1" }, selectIdentity:true);
var post2Id = db.Insert(new Post { 
    CreatedBy = "gistlyn", Title = "Post 2", Body = "Body 2" }, selectIdentity:true);
db.Insert(new Tag { Id = 1, Name = "A" }, 
          new Tag { Id = 2, Name = "B" });
db.Insert(new PostTag { PostId = post1Id, TagId = 1 }, 
          new PostTag { PostId = post1Id, TagId = 2 });
db.Insert(new PostTag { PostId = post2Id, TagId = 1 });

创建一个SQL表达式加入所有相关表:

如果按照上述OrmLite正常的命名惯例, OrmLite可以推断出各表之间的关系从指定每个查询,如联接表达式为您节省:

var postsWithTagB = db.Select(db.From<Post>()
                                .Join<PostTag>()
                                .Join<PostTag,Tag>()
                                .Where<Tag>(x => x.Name == "B"));
postsWithTagB.PrintDump();

当此查询返回只是标签后的第一个B和两个帖子标记A

您还可以通过网上探讨这个独立的例子直播上运行它Gistlyn 。

填充有标签和评论全部文章

如果这是一个小博客,要加载所有的职位有,例如在主页或RSS订阅,你可以在内存使用Linq2Objects喜欢的东西加入其中4个查询加载整个数据集及其相关的标签和评论:

//Only 4 DB calls to read all table data
var posts = Db.Select<Post>();
var postTags = Db.Select<PostTag>();
var tags = Db.Select<Tag>();
var comments = Db.Select<Comment>();

//using Linq2Objects to stitch the data together
var fullPosts = posts.ConvertAll(post =>
{
    var postTagIds = postTags
        .Where(x => x.PostId == post.PostId)
        .Select(x => x.PostTagId).ToList();

    return new PostFull {
        Post = post,
        Tags = tags.Where(x => postTagIds.Contains(x.TagId)).ToList(),
        Comments = comments.Where(x => x.PostId == post.PostId).ToList(),
    };
});


Answer 2:

您不必包括标签和注释,为邮政的实体。 在你的情况你的DTO和DB模型类应该是不同的。 在标签和评论类,你应该有房地产帖子ID。

在服务你应该查询评论哪里等于帖子ID后您的ID和标签做同样的。 结果应加入到含有的评论和标签列表后您的DTO。



文章来源: ServiceStack / ORM Lite - Foreign Key Relationships