Linq-to-sql on a list of rows from a concatenated table

I have a DB table [Table1] with a one to many relationship.
This linked table [Table2] has a type field that is a string.

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

I am trying to create a summary of how often each combination of types happens and I am trying to do as much work as possible with the DB as it is too slow to have it all in memory.

The code I have but seems repetitive to me.

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

      

Is there a way to group by this list of rows so that I can do grouping in the DB and also reduce the number of select statements in my code

+3


source to share


1 answer


Linq to SQL doesn't support Aggregate

either String.Join

or the corresponding SQL tricks, so if you don't want to use a stored procedure, some of them must be done client-side.

One alternative is to create the groups first and then send them back to the server to count matches, but this doesn't seem like a gain.

I think the best you can do is something like

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

      



I ordered Type

owned item

to match when grouped. Some of the sqlans will be executed by the server, but the rest must be executed on the client for processing String.Join

.

Instead of using EF, I would be tempted to work with Table2 (by making a left semi-join if you can have orphans of records in table2) directly

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

      

0


source







All Articles