我有以下问题要解决,希望以最佳的方式获得帮助。
我已附上一张图像,显示了4个表的设置(EF删除了一些多对多关系的链接表)。
我试图通过LINQ
查询获取的内容的简要概述:
(我尝试使用方法语法)。系统将允许用户在类别下(取决于他们是否可以访问类别)提交帖子以供查看,然后再显示。类别具有顶级父主题,因此具有自引用表(但将来可能会扩展许多子级)。每个帖子可以属于1个或多个类别,即,一个帖子可以大约为sports
和IT
(我知道这是个愚蠢的例子)。每个类别可以有一个或多个批准者。 announcement_approver
表将记录&成为基于过程的表,其中一个或多个批准者将必须记录该帖子是否已被编辑,拒绝批准或被他们批准。这将在announcement_posts
表中设置一个标志(因此一对多)。
我需要获取的是所有announcement_posts
的列表,这些列表未被批准/待审批(状态为false),并由特定批准者的Parent> Child关系分解(where子句将基于(在categories_approvers
表的用户名字段中)。希望我已经在这里正确解释了。
我尝试了一种从category
表开始的方法,将.include用于类别(自引用),ICollections
和cat_approvers
的虚拟announcements_posts
。然后,我尝试将announcements_posts
加入announcements_approvers
。
我无法正常工作。我确实考虑过从posts表向后工作,并包括cat表和announces_approvers,但我认为将Category依次加入Category和然后批准者是一个棘手的情况。
对不起,如果我在这里摇晃一下。
Db Schema Desired Output hierarchy
Many to Many Category to Posts
编辑:
我尝试从某些代码开始,但没有获得喜悦。这不包括任何where子句,因此其基本上是所有类别及其子项,职位,批准者和rovaling_posts。我觉得自己陷入困境,需要重设:)
List<Category> res = db.Categories
.Include(a => a.ChildrenCategories)
.Include(a => a.Categories_approvers)
.Include(a => a.Announcement_posts)
.Include(a => a.Announcement_posts.Select(a1 => a1.Announcement_approvals).ToList())
.ToList();
答案 0 :(得分:0)
因为没有用于多对多外键的链接表,所以这很难编写。如果您有可能更改数据模型,则应该确实这样做(此模型很糟糕)。您应该引入一个“ Announcement_Categories”或“ Category_Announcements”表,该表只有两个用于类别和公告的外键,然后此代码才能工作:
var approveposts =
db.Announcement_Categories
.Where(a => a.Announcement.Announcement_Approvers.Any() == false)
.GroupBy(a => a.Category);
foreach (var categorygroup in approveposts)
{
var category = categorygroup.Key;
var posts = categorygroup.ToList();
// Find parents
var parents = new List<Category>();
var parentcategory = category.Parent;
while (parentcategory != null)
{
parents.Insert(0, parentcategory);
parentcategory = parentcategory.Parent;
}
// Show data
}
如果没有此选项,则应建立模型来存储所有加载的信息
db.Announcements.Where(a => a.Announcement_Approvers.Any() == false)
项。如果您不知道如何操作,请告诉我。
编辑:
添加了初始化:
var categorygroups = new List<KeyValuePair<Category, List<Announcement>>>();
var approveposts = db.Announcements
.Where(a => a.Announcement_Approvers.Any() == false)
.ToList();
foreach (var post in approveposts)
{
foreach (var category in post.Categories)
{
var categorygroup = categorygroups.FirstOrDefault(a => a.Key.Id == category.Id);
if (categorygroup == null)
{
categorygroup = new KeyValuePair<Category, List<Announcement>>(category, new List<Announcement>());
categorygroups.Add(categorygroup);
}
categorygroup.Value.Add(post);
}
}
foreach (var categorygroup in categorygroups)
{
var category = categorygroup.Key;
var posts = categorygroup.Value;
// Find parents
var parents = new List<Category>();
var parentcategory = category.Parent;
while (parentcategory != null)
{
parents.Insert(0, parentcategory);
parentcategory = parentcategory.Parent;
}
// Show data
}
答案 1 :(得分:0)
感谢ikwillem的协助,但我寻求另一种方法,并坚持使用实体框架和linq。
对于任何对我的解决方案感兴趣的人来说。我遵循EF包含方法,并使用嵌套选择进行了一些反复试验,得到了我所需的信息。然后,我仅将其投影到新的Vm中。为了简单起见,我删除了一些where子句。
var currentUser = Authentication.GetGlobalUserName();
db.Configuration.LazyLoadingEnabled = false;
//this is working from posts back to categories.
var approveposts = db.Announcement_posts
.Include(a => a.Categories)
.Include(a => a.Categories.Select(b => b.ParentCategory))
.Include(a => a.Categories.Select(c => c.Categories_approvers))
.Include(a => a.Announcement_approvals)
.Where(a => a.Announcement_approvals
.Any(b => b.approver == currentUser && a.approved == false)
.Select(p => new PendingPostsVm
{
PostGuid = p.postGUID,
Topic = p.Categories.Select(cat => cat.name).FirstOrDefault(),
Theme = p.Categories.Select(cat => cat.ParentCategory.name).FirstOrDefault(),
PostTitle = p.title,
Catid = p.Categories.Select(cat => cat.id).FirstOrDefault(),
DateSubmitted = p.date_created
})
.OrderBy(s => s.DateSubmitted)
.ToList();