同様の質問に対するいくつかの回答を見てきましたが、自分の問題に回答を適用する方法を考え出すことはできません。
var allposts = _context.Posts
.Include(p => p.Comments)
.Include(aa => aa.Attachments)
.Include(a => a.PostAuthor)
.Where(t => t.PostAuthor.Id == postAuthorId).ToList();
添付ファイルは、作成者(作成者タイプ)または投稿者(投稿者タイプ)によってアップロードできます。私がやりたいのは、添付ファイルの所有者がAuthorタイプのAttachmentsのみを取得することです。
私はこれが機能せず、エラーが発生することを知っています:
.Include(s=>aa.Attachments.Where(o=>o.Owner is Author))
ここでフィルターされた投影について読みました
編集-記事へのリンク: http://blogs.msdn.com/b/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx 、
しかし、私はちょうどそれを回避することはできません。
すべての投稿が必要なため、最後のwhere句にフィルターを含めたくありませんが、著者に属する投稿の添付ファイルのみを取得したいです。
編集2:-要求された投稿スキーマ
public abstract class Post : IPostable
{
[Key]
public int Id { get; set; }
[Required]
public DateTime PublishDate { get; set; }
[Required]
public String Title { get; set; }
[Required]
public String Description { get; set; }
public Person PostAuthor { get; set; }
public virtual ICollection<Attachment> Attachments { get; set; }
public List<Comment> Comments { get; set; }
}
投稿したリンクから、1対多(または多対1)の関係でのみトリックが機能することを確認できます。この場合、Post-Attachment
は1対多の関係である必要があるため、完全に適用可能です。必要なクエリは次のとおりです。
//this should be disabled temporarily
_context.Configuration.LazyLoadingEnabled = false;
var allposts = _context.Posts.Where(t => t.PostAuthor.Id == postAuthorId)
.Select(e => new {
e,//for later projection
e.Comments,//cache Comments
//cache filtered Attachments
Attachments = e.Attachments.Where(a => a.Owner is Author),
e.PostAuthor//cache PostAuthor
})
.AsEnumerable()
.Select(e => e.e).ToList();
遅延読み込みを防ぐため、virtual
ナビゲーションプロパティからAttachments
キーワードを削除します。
public ICollection<Attachment> Attachments { get; set; }
最初の方法:2つの個別のクエリを発行します。1つは投稿用、もう1つは添付ファイル用で、残りはリレーションシップの修正で処理します。
List<Post> postsWithAuthoredAttachments = _context.Posts
.Include(p => p.Comments)
.Include(p => p.PostAuthor)
.Where(p => p.PostAuthor.Id == postAuthorId)
.ToList();
List<Attachment> filteredAttachments = _context.Attachments
.Where(a => a.Post.PostAuthor.Id == postAuthorId)
.Where(a => a.Owner is Author)
.ToList()
関係の修正により、投稿のナビゲーションプロパティを介してこれらのフィルターされた添付ファイルにアクセスできます。
2番目の方法:データベースへの1つのクエリとそれに続くメモリ内クエリ:
var query = _context.Posts
.Include(p => p.Comments)
.Include(p => p.PostAuthor)
.Where(p => p.PostAuthor.Id == postAuthorId)
.Select(p => new
{
Post = p,
AuthoredAttachments = p.Attachments
Where(a => a.Owner is Author)
}
);
ここでは匿名型を使用します
var postsWithAuthoredAttachments = query.ToList()
または、匿名型を回避するためにViewModelクラスを作成します。
List<MyDisplayTemplate> postsWithAuthoredAttachments =
//query as above but use new PostWithAuthoredAttachments in the Select
または、本当に投稿を展開したい場合:
List<Post> postsWithAuthoredAttachments = query.//you could "inline" this variable
.AsEnumerable() //force the database query to run as is - pulling data into memory
.Select(p => p) //unwrap the Posts from the in-memory results
.ToList()
拡張メソッドの この実装 を使用できます(例)Include2()
。その後、次を呼び出すことができます。
_context.Posts.Include2(post => post.Attachments.Where(a => a.OwnerId == 1))
上記のコードには、Attachment.OwnerId == 1
。