我想知道如何将此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 );
}
提前谢谢你。
答案 0 :(得分:21)
以下是根据您提供的信息在一个查询中执行此操作的方法。
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表,那么你仍然可以从博客开始,并使用正确配置的集合和引用属性来获取这样的帖子。
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本身的EntityFramework 和 C#语言功能,例如LINQ。将问题分解为其组成部分可以帮助您解决问题,并使研究更容易进行更复杂的操作。单独学习和练习LINQ将帮助您更好地使用EntityFramework。
答案 1 :(得分:2)
LINQ查询
~
SQL
from p in _context.Post
where _context.BlogCategory.Any
( bc => bc.PostId == p.PostId
&& bc.BlogId == &id
)
select p;
OR
SELECT *
FROM Post
WHERE PostId IN (
SELECT PostId FROM BlogCategory
WHERE BlogId = &id);
答案 2 :(得分: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();
这是基于代码顶部的Sql
SELECT *
FROM Post
WHERE PostId IN (
SELECT PostId FROM BlogPost WHERE BlogId = &id);
答案 3 :(得分:0)
<强> EDITED 强>
您可以使用.Select()
var blog = await _context.Blogs.FirstOrDefaultAsync(b => b.Id == blogId);
var posts = blog ?? blog.BlogCategory.Select(bp => bp.Post);
我猜您在Blog
BlogCategory
中有导航属性
您可能会发现这有用link