3

私は次の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; }
}

CommentTagエンティティにFKがあります。それで、私は私のサービスからの私の応答でそれらを返したいのですが、それは'Invalid Column name 'Comments''と言い'Invalid Column name 'Tags''ます。ORM Liteを使用して、投稿に添付されているコメントとタグを確認するにはどうすればよいですか?EFでは、単にIncludeを使用して、関連するテーブル情報を遅延ロードします。同等のものは何ですか?

編集

答えに応えて、私はこれをしました:

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

次に、私のサービスでは、これを返します。私のエンティティはM:M関係であるため、私のエンティティPostTagは交差エンティティです。PostTag

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

2 に答える 2

6

OrmLite のテーブルは、基礎となる db テーブルと厳密に1:1 のマッピングです。

これは、すべての複雑なタイプのプロパティが、プロパティ名を含む db テキスト フィールドにブロブされることを意味します。ここで期待するように、子リレーションへの自動マッピングには使用されません。

OrmLite を使用して多対多の関係をマッピングする方法を示す初期の回答を次に示します。

N+1クエリを避けるようにしてください。すべての呼び出しがリモート DB クエリであることを覚えておいてDb.xください。理想的には、ループ内のデータベース呼び出しを避けるようにしてください。

多対多のテーブル クエリによる投稿の取得

OrmLite の JOIN のサポートを使用して、通常の SQL で多対多テーブルでクエリを実行し、指定されたタグを持つすべての投稿を検索するように、型指定されたクエリを作成できます。

投稿を作成してテスト データを入力する
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 は各テーブル間の関係を推測でき、クエリごとに JOIN 式を指定する手間を省くことができます。

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

このクエリは、 Tag の最初の Post と TagBの両方の Post のみを返しますA

Gistlyn で Live を実行することにより、このスタンドアロンの例をオンラインでさらに調べることができます。

すべての投稿にタグとコメントを追加する

これが小さなブログで、関連するタグとコメントを含むすべての投稿を読み込みたい場合、たとえばホームページや 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(),
    };
});
于 2013-01-24T14:57:45.717 に答える
2

タグとコメントを Post エンティティに含める必要はありません。あなたの場合、DTO と DB モデル クラスは異なるはずです。Tag および Comment クラスでは、PostId プロパティが必要です。

サービスでは、PostId が投稿 ID と等しいコメントをクエリし、タグについても同じことを行う必要があります。結果は、コメントとタグのリストを含む Post DTO に追加する必要があります。

于 2013-01-24T15:00:32.567 に答える