2016-12-21 26 views
4

このSQLクエリをエンティティフレームワーククエリに変換する方法を知りました。Entity Frameworkコア - IN節同等

SELECT * 
FROM Post 
WHERE PostId IN (
SELECT PostId FROM BlogPost 
WHERE BlogId = &blogId); 

特定のカテゴリIDを持つ投稿のリストを取得しようとしています。簡略化され

データベース:

ブログ(ポストのカテゴリ):

BlogId 
Title 
.. 

ポスト:

PostId 
Title 
.. 

ブログ投稿2つのテーブルを組み合わせて、あなたはポストごとに複数のカテゴリを持つせるため:

PostId 
BlogId 

これは私がすでに持っているものですが、ofcourseのクエリが動作していない:

public async Task<IActionResult> Category(int? id) 
     { 
      int blogId = id; 

      if (blogId == null) 
      { 
       return NotFound(); 
      } 
      ICollection<Post> posts = await _context.Post.Where(pid => pid.PostId.Contains(_context.BlogPost.Where(i => i.PostId == blogId).ToListAsync())).ToListAsync(); 

      if (posts == null) 
      { 
       return NotFound(); 
      } 

      return View(posts); 
     } 

は、事前にありがとうございます。

答えて

7

ここでは、提供した情報に基づいて1つのクエリでそれを行う方法を説明します。ここで

var posts = await _context.Post 
    .Where(post => 
     _context.BlogPost.Any(bp => bp.BlogId == blogId && bp.PostId == post.PostId) 
    ) 
    .ToListAsync(); 

は、私はあなたが提供された情報に基づいてContainsを使用するために、2つのクエリでそれを行うだろう方法です。ここで

var postIds = await _context.BlogPost 
    .Where(bp => bp.BlogId = blogId) 
    .Select(bp => bp.PostId) 
    .ToArrayAsync(); 
var posts = await _context.Post 
    .Where(p => postIds.Contains(p.PostId)) 
    .ToListAsync(); 

は、私は貴重なEntityFramework機能を使用していた場合、私は1つのクエリでそれを行うだろうかある、と私はブログ投稿のポストという名前の参照プロパティを持っていました。ここで

var posts = await _context.BlogPost 
    .Where(bp => bp.BlogId == blogId) 
    .Select(bp => bp.Post) 
    .ToListAsync(); 

私は貴重なEntityFramework機能を使用していた、と私はブログから記事をという名前のコレクションプロパティを持っていた、と多くの-多くのブログ投稿のテーブルは、このようなAでEntityFrameworkによって隠されていた場合、私は1つのクエリでそれを行うだろうかですあなたはC#から実際にそれと対話することはありません。多くの-多くのブログ投稿のテーブルはEntityFrameworkによって公開されている場合

var posts = await _context.Blog 
    .Where(b => b.BlogId == blogId) 
    .SelectMany(b => b.Posts) 
    .ToListAsync(); 

一方で、あなたはまだブログで開始し、そのようなポストに到達するために適切に構成コレクション参照プロパティを使用することができます。

var posts = await _context.Blog 
    .Where(b => b.BlogId == blogId) 
    .SelectMany(b => b.BlogPosts) 
    .Select(bp => bp.Post) 
    .ToListAsync(); 

それとも

var posts = await _context.Blog 
    .Where(b => b.BlogId == blogId) 
    .SelectMany(b => b.BlogPosts.Select(bp => bp.Post)) 
    .ToListAsync(); 

テイクアウト、EntityFrameworkはSQLではありません。 SQLで行うことは、直接マップすることも、マップしないこともあります。また、EntityFrameworkでどのように行うかにも適用できます。それだけでなく、EntityFrameworkを使用している場合は、EntityFrameworkそれ自体ではないC#言語機能、例えばLINQなど、EntityFramework を使用しています。問題を構成部分に分解することで、問題を解決し、より複雑な操作を実行できるように勉強するのを容易にすることができます。孤立してLINQを勉強し、練習することは、EntityFrameworkでよりうまくいくのに役立ちます。

+0

を見つけることができます。カテゴリに属する​​投稿のリストではなく、投稿が属するカテゴリを返そうとしています。 –

+0

データベーステーブルの名前を変更して、わかりやすくしました。私はカテゴリに属する​​投稿のリストを取得しようとしています(ブログは投稿のカテゴリです) – QuanDar

+0

ご清聴ありがとうございます。私はEntityFrameworkとLINQについて考えさせるためにたくさんの例を追加しました。うまくいけば、両方の技術に関するオンラインコースを勉強したり見たりすることをお勧めします。 –

0

ブログへの投稿の関係で結合を使用し、ブログのフィルタとしてwhere句を使用できます。

var query = from post in _context.Post 
    join blogCat in _context.BlogPost on post.PostId equals blogCat.PostId 
    where blogCat.BlogId == blogId 
    select post; 

var result = await query.ToListAsync(); 

これはあなたのコードの先頭

SELECT * 
FROM Post 
WHERE PostId IN (
    SELECT PostId FROM BlogPost WHERE BlogId = &id); 
0

にSQLに基づいていますEDITED

あなたは.Select()

var blog = await _context.Blogs.FirstOrDefaultAsync(b => b.Id == blogId); 
var posts = blog ?? blog.BlogCategory.Select(bp => bp.Post); 

を使用することができます私はあなたがナビゲーションプロパティを持っていると思いますin BlogBlogCategory あなたは、私が再読み込み、あなたのコードの後に​​これを更新し、この便利link

2

LINQクエリ

from p in _context.Post 
where _context.BlogCategory.Any 
       (bc => bc.PostId == p.PostId 
        && bc.BlogId == &id 
       ) 
select p; 

SQL

SELECT * 
FROM Post 
WHERE PostId IN (
SELECT PostId FROM BlogCategory 
WHERE BlogId = &id); 

OR

SELECT * 
FROM Post p 
WHERE EXISTS 
    (
     SELECT 1 FROM BlogCategory 
     WHERE PostId = p.PostID AND BlogId = &id 
    ); 
関連する問題