关注this answer我试图这样做:
var posts = await _context.Posts
.Select(p => new
{
p,
Comments = p.Comments
.Where(c.Status == "approved")
})
.Include(p => p.Author)
.Include(p => p.Comments)
.SingleOrDefaultAsync(m => m.Id == id);
仅获得批准"我的帖子评论。
但是我收到以下错误:
名称' c'在当前上下文中不存在[ASPress]
所以我不能用语法
来解决问题答案 0 :(得分:3)
您必须在lambda ...
中定义您正在使用的标识符.Where(c => c.Status == "approved")
应该修复它。
刚刚阅读了您的评论,我相信它是基于您使用LINQ方法的顺序。从Posts
开始,您将投射到匿名类型,并且不会拥有您想要的内容。尝试重新安排它,如下所示:
var posts = await _context.Posts
.Include(p => p.Author)
.Include(p => p.Comments)
.Select(p => new
{
p,
Comments = p.Comments
.Where(c => c.Status == "approved")
})
答案 1 :(得分:1)
虽然您忘记编写课程,但在我看来,您有一系列帖子。邮政只有一个作者。每个帖子都有零个或多个评论,每个评论都属于一个帖子:没有任何评论都没有,帖子和评论之间存在真正的一对多关系。
如果您按照guidelines for a one-to-many configuration进行操作,则会有以下类似内容:
class Author
{
public int Id {get; set;}
// not certain, but very likely: every Author has zero or more Posts:
public virtual ICollection<Post> Posts {get; set;}
}
class Post
{
public int Id {get; set;}
// Every Post is posted by exactly one Author, using foreign key
public int AuthorId {get; set;}
public virtual Author Author {get; set;}
// Every Post has zero or more Comments:
public virtual ICollection<Comment> Comments {get; set;}
}
class Comment
{
public int Id {get; set;}
// every Comment belongs to exactly one Post using foreign key
public int PostId {get; set;}
public virtual Post Post {get; set;}
public string Status {get; set;}
}
因为我遵循entity framework naming conventions,这足以告诉实体框架主键,外键和一对多关系。如果您决定偏离命名约定,您可能需要一些流畅的API属性,但这个想法保持不变。
回到你的问题
在我看来,你想要所有的帖子,连同他们的作者,只有他们批准的评论。
使用Include语句从数据库中获取数据。这通常是浪费处理能力,因为您可能不会使用所有Post属性和所有Comment Properties。最好明确命名您计划使用的属性。
var result = myDbcontext.Posts.Select(post => new
{
// query only the attributes you plan to use, for example:
Id = post.Id,
Title = post.Title,
Author = new
{
Id = post.Author.Id,
Name = post.Author.Name,
// no need to query the foreign Key Author.PostId, I already got that one in property Id
... // other author properties you need
},
Comments = post.Comments
.Where(comment => comment.Status == "approved")
.Select(comment => new
{ // again: query only the properties you plan to use:
Text = comment.Text,
...
}
.ToList(),
...
};
根据我的经验,如果您正确配置一对多关系,则很少需要加入。请改用ICollections。实体框架将知道需要加入。
但是,您可以使用联接获得相同的结果:
var result = myDbContext.Posts
.Join(myDbContext.Comments.Where(comment => comment.Status = "approved"),
post => post.Id, // from every Post take the Id
comment => comment.PostId // from every Comment take the PostId
(post, comment) = new // when they match make a new object
{
Id = post.Id,
Title = post.Title,
CommentText = comment.Text,
}
等。请注意,这是一个真正的内部联接。如果您想要“发布评论”,则需要执行GroupBy Id
最后:如果您的状态数量有限,请考虑为您的状态创建枚举。这样可以防止人们将“已批准”分配给州而不是“已批准”,或者更糟糕的是:错误如“已批准”?在数据库内部,它们仍然是字符串,但是实体框架会将它们解析为正确的枚举值,并且您将无法在数据库中放置不正确的值。