【发布时间】:2015-12-17 17:35:38
【问题描述】:
希望我只是遗漏了一些明显的东西,但这是我的查询
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 的自定义设置器,但是对于查询返回的每个所有者,这仍然会再次往返于数据库。
那么您应该如何在子查询中分配基本列表?
编辑和回答(因为 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语句,因此不会抛出异常。
每天学习新东西。
【问题讨论】:
-
如果你设置了导航属性,这会干净很多。
标签: c# sql-server linq-to-entities