Je me demande comment convertir cette requête SQL en une requête de structure d'entité.
SELECT *
FROM Post
WHERE PostId IN (
SELECT PostId FROM BlogPost
WHERE BlogId = &blogId);
J'essaie d'obtenir une liste de messages avec un identifiant de catégorie donné.
Base de données simplifiée:
Blog (la catégorie de l'article):
BlogId
Title
..
Publier:
PostId
Title
..
BlogPost pour combiner les deux tableaux et vous permettre d'avoir plusieurs catégories par article:
PostId
BlogId
C'est ce que j'ai déjà, mais bien sûr la requête ne fonctionne pas:
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 );
}
Merci d'avance.
Voici comment je le ferais dans une requête basée sur les informations que vous avez fournies.
var posts = await _context.Post
.Where(post =>
_context.BlogPost.Any(bp => bp.BlogId == blogId && bp.PostId == post.PostId)
)
.ToListAsync();
Voici comment je le ferais dans deux requêtes afin d'utiliser Contains
en fonction des informations que vous avez fournies.
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();
Voici comment je le ferais dans une seule requête si j'utilisais de précieuses fonctionnalités EntityFramework et que j'avais une propriété de référence nommée Post sur BlogPost.
var posts = await _context.BlogPost
.Where(bp => bp.BlogId == blogId)
.Select(bp => bp.Post)
.ToListAsync();
Voici comment je le ferais dans une seule requête si j'utilisais de précieuses fonctionnalités EntityFramework, et j'avais une propriété de collection nommée Posts from Blog, et la table de nombreux BlogPost était cachée par EntityFramework de telle manière que vous n'interagissiez jamais réellement avec à partir de C #.
var posts = await _context.Blog
.Where(b => b.BlogId == blogId)
.SelectMany(b => b.Posts)
.ToListAsync();
D'un autre côté, si la table plusieurs-plusieurs BlogPost est exposée par EntityFramework, vous pouvez toujours commencer sur le blog et utiliser des propriétés de collection et de référence correctement configurées pour accéder aux publications de cette manière.
var posts = await _context.Blog
.Where(b => b.BlogId == blogId)
.SelectMany(b => b.BlogPosts)
.Select(bp => bp.Post)
.ToListAsync();
Ou
var posts = await _context.Blog
.Where(b => b.BlogId == blogId)
.SelectMany(b => b.BlogPosts.Select(bp => bp.Post))
.ToListAsync();
À emporter, EntityFramework n'est pas SQL. Ce que vous faites dans SQL peut ou non être mappé directement, ou même s'appliquer à la façon dont vous le feriez dans EntityFramework. Non seulement cela, mais lorsque vous utilisez EntityFramework, vous utilisez EntityFramework et les fonctionnalités du langage C # qui ne sont pas EntityFramework en soi, LINQ par exemple. Décomposer le problème en ses éléments constitutifs peut vous aider à résoudre les problèmes et faciliter l'étude pour pouvoir effectuer des opérations plus complexes. L'étude et la pratique de LINQ isolément vous aideront à être meilleur avec EntityFramework.
Requête 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
);
Vous pouvez utiliser une jointure pour la relation post-blog, puis une clause where comme filtre de blog.
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();
Ceci est basé sur votre Sql en haut de votre code
SELECT *
FROM Post
WHERE PostId IN (
SELECT PostId FROM BlogPost WHERE BlogId = &id);
[~ # ~] modifié [~ # ~]
Vous pouvez utiliser .Select()
var blog = await _context.Blogs.FirstOrDefaultAsync(b => b.Id == blogId);
var posts = blog ?? blog.BlogCategory.Select(bp => bp.Post);
Je suppose que vous avez une propriété de navigation dans Blog
BlogCategory
Vous pouvez trouver cela utile link