希望我只是遗漏了一些明显的东西,但这是我的查询
var data = (from project in _db.Projects
where project.Id == id
let primaryCategory = (from c in _db.Categories
where c.CategoryID == project.PrimaryCategory
select c.Name)
let categories = (from c in _db.ProjectCategories
join pc in _db.Projects_ProjectCategories on c.ProjectCategoryID equals pc.ProjectCategoryID
where pc.ProjectID == project.ProjectID
select c.Name)
let owner = (from o in _db.Owners
join po in _db.App_Projects_Owners on o.OwnerID equals po.OwnerID
where po.ProjectID == project.ProjectID
select new OwnerModel
{
Owner = o,
Project = project,
PrimaryCategory = primaryCategory.FirstOrDefault(),
Categories = categories.ToList()
})
select new
{
owner,
project
}).FirstOrDefault();
在那里,OwnerModel.Categories是一个字符串列表。我无法在查询中使用ToList(),因为它会产生实现错误。我添加了一个带有IQueryable的自定义setter,但是仍然会为查询返回的每个所有者再次往返数据库。
那么你应该如何在子查询中分配基本列表呢?
编辑和答案(因为Robert McKee在评论中引导我回答)。
答案是像这样使用group by子句
var data = (from project in _db.Projects
where project.Id == id
let primaryCategory = (from c in _db.Categories
where c.CategoryID == project.PrimaryCategory
select c.Name)
let categories = (from c in _db.ProjectCategories
join pc in _db.Projects_ProjectCategories on c.ProjectCategoryID equals pc.ProjectCategoryID
where pc.ProjectID == project.ProjectID
group c.Name by pc.ProjectCategoryID into x
select x.ToList())
let owner = (from o in _db.Owners
join po in _db.App_Projects_Owners on o.OwnerID equals po.OwnerID
where po.ProjectID == project.ProjectID
select new OwnerModel
{
Owner = o,
Project = project,
PrimaryCategory = primaryCategory.FirstOrDefault(),
Categories = categories
})
select new
{
owner,
project
}).FirstOrDefault();
特别注意涉及
的位group c.Name by pc.ProjectCategoryID into x
select x.ToList()
在你深入研究究竟发生了什么之前,它可能看似违反直觉。我上面用categories.ToList()调用的方法试图使用System.Collection.Generics ToList函数,该列表没有任何方法将表达式转换为sql。但是,通过使用group by子句,我创建了一个专门的Enumerable IGrouping并在其上调用ToList函数。此函数可以转换为sql语句,因此不会抛出异常。
每天都学习新东西。
答案 0 :(得分:0)
设置导航属性,然后您的查询变为:
var data=db.Projects
.Include(p=>p.PrimaryCategory)
.Include(p=>p.Categories)
.Include(p=>p.Owner) // or .Include(p=>p.Owners) if projects can have multiple owners
.First(p=>p.Id == id);
对于子对象,您正在寻找group by
子句或.GroupBy
方法。