實體框架核心 - 相當於IN子句

asp.net-core entity-framework-core

我想知道如何將此sql查詢轉換為實體框架查詢。

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

我想獲得一個具有給定類別ID的帖子列表。

數據庫簡化:

博客(帖子的類別):

BlogId
Title
..

帖子:

PostId
Title
.. 

BlogPost用於組合這兩個表並讓每個帖子有多個類別:

PostId
BlogId

這是我已經擁有的,但當然查詢不起作用:

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

先謝謝你。

一般承認的答案

以下是根據您提供的信息在一個查詢中執行此操作的方法。

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

以下是我將如何在兩個查詢中執行此操作,以便根據您提供的信息使用Contains

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功能,我會在一個查詢中執行此操作,並且我在BlogPost上有一個名為Post的引用屬性。

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

如果我使用有價值的EntityFramework功能,我會在一個查詢中執行此操作,並且我有一個名為Posts from Blog的集合屬性,並且EntityFramework隱藏了許多BlogPost表,以至於您實際上從未與它來自C#。

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

另一方面,如果EntityFramework公開了許多BlogPost表,那麼您仍然可以從Blog開始並使用正確配置的集合和引用屬性來獲取這樣的帖子。

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#語言功能本身不是EntityFramework,例如LINQ 。將問題分解為其組成部分可以幫助您解決問題,並使研究更容易進行更複雜的操作。單獨學習和練習LINQ將幫助您更好地使用EntityFramework。


熱門答案

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);

要么

SELECT * 
FROM Post p
WHERE EXISTS
    (
      SELECT 1 FROM BlogCategory
      WHERE PostId = p.PostID AND BlogId = &id
    );


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow