linq-to-sql group by连接表中的字符串列表

时间:2017-03-29 12:05:24

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

我有一个与一对多关系的数据库表[表1] 该相关表[Table2]具有类型字段,该字段是字符串。

Table 1          Table 2
Field | Type     Field    | Type
------|-----     ---------|-----
Id    | int      Id       | int
                 Table1Id | int
                 Type     | string

我正在尝试创建每种类型组合发生频率的摘要, 并且我试图在数据库上做尽可能多的工作,因为它太慢而无法将其全部存入内存。

我的代码有效但似乎对我重复。

        items
        .Where(x => x.Table2s.Count > 1)
        .Select(x => new
        {
            Type = x.Table2s.Select(y => y.Type)
        })
        .ToList() // into memory as string.join has no translation into sql
        .Select(x => new
        {
            Type = string.Join(",", x.Type) // no sql translation
        })
        .GroupBy(x => x.Type) // can't work on IEnumerable[string]
        .Select(x => new Result()
        {
            Type = x.Key,
            Count = x.Count()
        })
        .OrderByDescending(x => x.Count)
        .ToList();

是否有办法按此字符串列表进行分组,以便我可以对数据库进行分组,并减少代码中的select语句数

1 个答案:

答案 0 :(得分:0)

Linq to SQL不支持AggregateString.Join或相应的SQL技巧,因此除非您想使用存储过程,否则一些工作必须在客户端进行。

另一种方法是首先创建分组,然后将它们发送回服务器以计算匹配数,但这似乎不是一个好处。

我认为你能做的最好就是

var sqlans = items.Where(x => x.Table2s.Count > 0).AsEnumerable();
var ans = sqlans.Select(x => String.Join(",", x.Table2s.Select(t2 => t2.Type).OrderBy(ty => ty).ToArray())).GroupBy(ty => ty, ty => ty, (key, g) => new { key, Count = g.Count() });

我订购了属于Type的{​​{1}},以便在分组时匹配。 sqlans部分将由服务器执行,但其余部分必须在客户端上执行以处理item

而不是使用EF我会试图在Table2上工作(如果你可能有孤立的Table2条目那么做左半连接)

String.Join