LINQ Lambda,带列表的分组

9

我在寻找正确的语法来实现以下操作时遇到了一些麻烦:

使用LINQ(Lambda表达式),是否可以通过.GroupBy数据,而不是使用通常的.Sum()或.Count(),将结果数据作为Int类型的List返回。

我定义了自己的类Filter_IDs。它的构造函数需要两个参数:

public int? type; // Represents the object_type column from my database
public List<int?> objects; // Represents the object_id column from my database

我希望从我的数据库中加载数据到这个对象中。下面的LINQ查询应该返回一个Filter_IDs列表:
下面的LINQ查询应该返回一个Filter_IDs列表:
List<Filter_IDs> filterids = ef.filterLine
        .GroupBy(fl => fl.objectType)
    .Select(fl => new Filter_IDs { type = fl.Key, objects = fl.Select(x => x.object_id).ToList() })
    .ToList();

使用这个查询不会出现构建错误,但在运行时会出现“NotSupportedException”的错误。
为了更好地理解数据,数据库如下图所示: http://d.pr/i/mnhq+ (droplr image)
谢谢, Gerben

ef是上下文,filterLine是包含object_id和objectType的数据库表。 - gerb0n
如果你执行 ef.filterLine.ToList(),会起作用吗? - Jon B
可以这样做,但是filterLine除了objectid和objectType之外还有更多的列。我不想要其他列中的值。 - gerb0n
3个回答

12

我认为问题在于DB无法在select语句中调用ToList函数,也无法创建一个新的Filter_ID。

尝试像这样:

List<Filter_IDs> filterids = ef.filterLine.Select(o => new { objectType = o.objectType, object_id=o.object_id})
    .GroupBy(fl => fl.objectType).ToList()
    .Select(fl => new Filter_IDs { type = fl.Key, objects = fl.Select(x => x.object_id).ToList() })
    .ToList();

这是正确的,对我有用。非常感谢大家和 Kek。 - gerb0n

1

也许你想要

IList<Filter_IDs> filterIds = ef.filterline
    .Select(fl => fl.objectType).Distinct()
    .Select(ot => new Filter_IDs
        {
            type = ot,
            objects = ef.filterline
                          .Where(fl => fl.objectType == ot)
                          .Select(fl =>objectType)
                          .ToList()
        }).ToList();

获取不同的列表objectType,并使用它来为每个object_id列表进行子查询。
然而,对我来说,直接按顺序枚举这些值似乎更有效率。
var results = new List<Filter_IDs>();
var ids = new List<int>();
var first = true;
int thisType;

foreach (var fl in ef.filterLines
                       .OrderBy(fl => fl.objectType)
                       .ThenBy(fl => fl.object_Id))
{
    if (first)
    {
        thisType = fl.objectType;
        first = false;
    }
    else
    {
        if (fl.objectType == thisType)
        {
            ids.Add(fl.object_Id);
        }
        else
        {
           results.Add(new Filter_IDs
                {
                    Type = thisType,
                    objects = ids
                });
           thisType = fl.objectType;
           ids = new List<int>();   
        }
    }    
}

0

您可以在客户端使用 GroupBy:

List<Filter_IDs> filterids = ef.filterLine
        .Select(fl=>new {fl.ObjectType, fl.object_id})
        .AsEnumerable()
        .GroupBy(fl => fl.objectType)
    .Select(fl => new Filter_IDs { type = fl.Key, objects = fl.Select(x => x.object_id).ToList() })
    .ToList();

我更喜欢在数据库中使用groupby。Kek给出的答案对我来说是正确的。感谢帮助! - gerb0n
Kek,一般来说这取决于索引等因素,但在这种情况下,我想你是正确的。我们可以将AsEnumerable()下移一行 :) - Kirill Bestemyanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接