如何在LinqToEntities C#中分配List <string>

时间:2015-12-17 17:35:38

标签: c# sql-server linq-to-entities

希望我只是遗漏了一些明显的东西,但这是我的查询

        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语句,因此不会抛出异常。

每天都学习新东西。

1 个答案:

答案 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方法。