C# 如何使用LINQ将查询结果返回到字典

C# 如何使用LINQ将查询结果返回到字典,c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,我正在做一个MVC项目。我需要返回一个对象,该对象将菜单项分组为四个一组,以使用foreach迭代在视图中显示。由于这是一个传递给视图的模型,因此我需要返回一个可以绑定到.cshtml上的非泛型集合类 我的想法是,我可以根据LINQ中的某种计数类型对列表进行分组,以便为每个字典键添加四个新的列表项。然而,我还没有找到一个表达式能够满足字典的要求。我可以通过创建另一个方法并在集合中再次迭代以基于计数分配键来很容易地解决这个问题,但这似乎是不必要的迭代和糟糕的做法 目前,我正在处理以下查询

我正在做一个MVC项目。我需要返回一个对象,该对象将菜单项分组为四个一组,以使用foreach迭代在视图中显示。由于这是一个传递给视图的模型,因此我需要返回一个可以绑定到.cshtml上的非泛型集合类

我的想法是,我可以根据LINQ中的某种计数类型对列表进行分组,以便为每个字典键添加四个新的列表项。然而,我还没有找到一个表达式能够满足字典的要求。我可以通过创建另一个方法并在集合中再次迭代以基于计数分配键来很容易地解决这个问题,但这似乎是不必要的迭代和糟糕的做法

目前,我正在处理以下查询

        var itemsDict = rssDataContext.rss_Application_Blog_Category_Relationships
            .Where(x => x.Application_Blog.rss_Application.ID == 1)
            .Where(x => x.Blog_Category_ID == 1)
            .Select(x => new MenuItem
            {
            Name = x.rss_Application_Blog.Blog_Title,
            Uri = x.rss_Application_Blog.Blog_Uri,
            ID = x.rss_Application_Blog.ID
            });

但是有没有一种方法可以将这个查询分成4个类的组,并填充到字典中呢

我想你可以这样做:

var itemsDict = rssDataContext.rss_Application_Blog_Category_Relationships
    .Where(x => x.Application_Blog.rss_Application.ID == 1)
    .Where(x => x.Blog_Category_ID == 1)
    .Select(x => new { 
        x.rss_Application_Blog.BlogTitle,
        x.rss_Application_Blog.BlogUri,
        x.rss_Application_Blog.ID
    })
    .AsEnumerable() // Do the rest of the query in-process
    .Select((value, index) => new { value, index })
    .ToLookup(pair => pair.index % 4,
              pair => new MenuItem {
                 Name = pair.value.Blog_Title,
                 Uri = pair.value.Blog_Uri,
                 ID = pair.value.ID
              });

请注意,这将返回一个查找,而不是一个字典,但实际上这是一个更接近您所需的模型。

我想您可以这样做:

var itemsDict = rssDataContext.rss_Application_Blog_Category_Relationships
    .Where(x => x.Application_Blog.rss_Application.ID == 1)
    .Where(x => x.Blog_Category_ID == 1)
    .Select(x => new { 
        x.rss_Application_Blog.BlogTitle,
        x.rss_Application_Blog.BlogUri,
        x.rss_Application_Blog.ID
    })
    .AsEnumerable() // Do the rest of the query in-process
    .Select((value, index) => new { value, index })
    .ToLookup(pair => pair.index % 4,
              pair => new MenuItem {
                 Name = pair.value.Blog_Title,
                 Uri = pair.value.Blog_Uri,
                 ID = pair.value.ID
              });

请注意,这将返回一个查找,而不是一个字典,但实际上这是一个更接近您所需的模型。

@JonSkeet的解决方案非常好。下面是一个替代实现,用于创建子列表并将其投影到最终结果中:

var itemsDict = rssDataContext.rss_Application_Blog_Category_Relationships
    .Where(x => x.Application_Blog.rss_Application.ID == 1)
    .Where(x => x.Blog_Category_ID == 1)
    .ToArray()
    .Select((x, index) => new
        {
            Index = index,
            Item = new MenuItem
            {
                Name = x.rss_Application_Blog.Blog_Title,
                Uri = x.rss_Application_Blog.Blog_Uri,
                ID = x.rss_Application_Blog.ID
            }
        });
    .GroupBy(i => i.Index / 4)
    .ToDictionary(g => g.Key);
生成的序列将如下所示:

items = new Dictionary<int, IGrouping<int>>()
{
    0, new[]
    {
        new { Index = 0, Item = new MenuItem { ... } },
        new { Index = 1, Item = new MenuItem { ... } }
    }
    1, new[]
    {
        new { Index = 2, Item = new MenuItem { ... } },
        new { Index = 3, Item = new MenuItem { ... } }
    }
};

@JonSkeet的解决方案相当不错。下面是一个替代实现,用于创建子列表并将其投影到最终结果中:

var itemsDict = rssDataContext.rss_Application_Blog_Category_Relationships
    .Where(x => x.Application_Blog.rss_Application.ID == 1)
    .Where(x => x.Blog_Category_ID == 1)
    .ToArray()
    .Select((x, index) => new
        {
            Index = index,
            Item = new MenuItem
            {
                Name = x.rss_Application_Blog.Blog_Title,
                Uri = x.rss_Application_Blog.Blog_Uri,
                ID = x.rss_Application_Blog.ID
            }
        });
    .GroupBy(i => i.Index / 4)
    .ToDictionary(g => g.Key);
生成的序列将如下所示:

items = new Dictionary<int, IGrouping<int>>()
{
    0, new[]
    {
        new { Index = 0, Item = new MenuItem { ... } },
        new { Index = 1, Item = new MenuItem { ... } }
    }
    1, new[]
    {
        new { Index = 2, Item = new MenuItem { ... } },
        new { Index = 3, Item = new MenuItem { ... } }
    }
};

我不清楚这里的钥匙是什么。我相信ToDictionary或ToLookup会让这件事变得容易,但如果不理解你想做什么,很难给出一个例子。某些类型的计数非常模糊。本质上,我需要将查询分组为4组,因此每个子列表中包含4个列表项,但我无法将其返回到泛型类型。因此,它必须返回到包含许多子列表的集合类型?只要视图未打开,您就可以对其使用泛型类型。例如,您可以使用IGrouping,但不能使用IGrouping。您希望对哪个属性进行分组?你说的是某种计数,但计数什么?这是一个正确的点。但是,我仍然需要一个填充iGroup的查询。我不清楚这里的键是什么。我相信ToDictionary或ToLookup会让这件事变得容易,但如果不理解你想做什么,很难给出一个例子。某些类型的计数非常模糊。本质上,我需要将查询分组为4组,因此每个子列表中包含4个列表项,但我无法将其返回到泛型类型。因此,它必须返回到包含许多子列表的集合类型?只要视图未打开,您就可以对其使用泛型类型。例如,您可以使用IGrouping,但不能使用IGrouping。您希望对哪个属性进行分组?你说的是某种计数,但计数什么?这是一个正确的点。但是,我仍然需要一个填充iGroup的查询。不幸的是,由于select运算符的重载不受支持,上述查询引发NotSupportedException。这是因为rss_Application_Blog_Category_Relationships属性返回的类型是IQueryable,并且基础LINQ提供程序不支持该投影。在应用Select方法之前,必须将源序列加载到内存中,方法是添加到Arrayor ToList。例如:。其中x=>x.Blog\u Category\u ID==1.ToArray.Select…不幸,由于select运算符的重载不受支持,上述查询引发NotSupportedException。这是因为rss_Application_Blog_Category_Relationships属性返回的类型是IQueryable,并且基础LINQ提供程序不支持该投影。在应用Select方法之前,必须将源序列加载到内存中,方法是添加到Arrayor ToList。例如:.Wherex=>x.Blog\u Category\u ID==1.ToArray.Select…我感谢大家的帮助。这也会抛出NotSupportedException。您是否在最后一个Where之后添加了ToArray或ToList。。。方法?我感谢大家的帮助。这也会抛出NotSupportedException。您是否在最后一个Where之后添加了ToArray或ToList。。。方法