简体   繁体   English

如何分配给列表 <string> 在LinqToEntities C#中

[英]How to assign to a List<string> in LinqToEntities C#

Hoping that I'm just missing something obvious but here's my query 希望我只是缺少明显的东西,但这是我的查询

        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();

In there OwnerModel.Categories is a List of strings. 在那里,OwnerModel.Categories是一个字符串列表。 I can't use ToList() in the query because it gives a materialization error. 我不能在查询中使用ToList(),因为它会出现实现错误。 I've added a custom setter that takes the IQueryable, but that still makes another round trip to the database for every owner that the query returns. 我添加了一个使用IQueryable的自定义设置器,但是对于查询返回的每个所有者,它仍然需要再次往返数据库。

So how are you supposed to assign basic lists in a subquery? 那么,应该如何在子查询中分配基本列表呢?

EDIT AND ANSWER (since Robert McKee lead me to the answer in his comment). 编辑和回答 (自Robert McKee带领我进入他的评论的答案)。

The answer is to use the group by clause like so 答案是像这样使用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();

Specifically note the bits involving 特别注意涉及的位

group c.Name by pc.ProjectCategoryID into x 
select x.ToList()

It may seem counter-intuitive that it works like this until you dig into exactly what's going on. 直到您深入了解正在发生的事情时,它的工作方式才如此似乎是违反直觉的。 The method that I was calling above with categories.ToList() was trying to use the System.Collection.Generics ToList function, and that list didn't have any way to convert the expression to sql. 我上面使用category.ToList()调用的方法试图使用System.Collection.Generics ToList函数,并且该列表没有任何将表达式转换为sql的方法。 However by using the group by clause I was creating a specialized Enumerable IGrouping and calling the ToList function on that. 但是,通过使用group by子句,我创建了一个特殊的Enumerable IGrouping并在其上调用ToList函数。 This function is able to be translated into a sql statement and thus doesn't throw the exception. 此函数能够转换为sql语句,因此不会引发异常。

Learn something new every day. 每天学些新东西。

Set up your navigation properties, and then your query becomes something like: 设置导航属性,然后查询将变为:

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);

As for child objects, you are looking for the group by clause or .GroupBy method. 至于子对象,您正在寻找group by子句或.GroupBy方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM