我有一个与一对多关系的数据库表[表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语句数
答案 0 :(得分:0)
Linq to SQL不支持Aggregate
或String.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