views:

37

answers:

1

Following linq statement generates multiple trips to the database, is there a way to change this so it does it in one trip?

db.Members.Distinct().Select(
    m => new { 
        Id = m.Id, 
        PlayTimeSchedules = m.PlayTimeSchedules.Select(pts => pts.DayOfWeek) }
).ToList();

FYI: in this example Distinct is redundant.

There is a one-to-many relationship between a member and his PlayTimeSchedule

I expect something like following to be generated:

select distinct(Members.Id), PlayTimeSchedule.DayOfWeek from Members 
join PlayTimeSchedule on PlayTimeSchedule.MemberId = Members.Id

or am I stuck with creating a view if I want it done in one trip?

EDIT: Here is what above linq generates (I have added .Take(20) for brevity):

    SELECT TOP (20) [t1].[Id]
    FROM (
        SELECT DISTINCT [t0].[Id], [t0].[EMail], [t0].[Username], [t0].[Password], [t0].[GmtOffset], [t0].[LastSeen], [t0].[Notifications], [t0].[EMailVer
    ified], [t0].[ObserveDst], [t0].[Admin], [t0].[AttendedRaidCount], [t0].[MissedRaidCount], [t0].[LedRaidCount], [t0].[CommittedRaidCount]
        FROM [dbo].[Members] AS [t0]
        ) AS [t1]
    -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

    SELECT [t0].[DayOfWeek]
    FROM [dbo].[PlayTimeSchedule] AS [t0]
    WHERE [t0].[MemberId] = @x1
    -- @x1: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
    -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

    SELECT [t0].[DayOfWeek]
    FROM [dbo].[PlayTimeSchedule] AS [t0]
    WHERE [t0].[MemberId] = @x1
    -- @x1: Input Int (Size = 0; Prec = 0; Scale = 0) [2]
    -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

    +++ 18 more DayOfWeek selections as above
+1  A: 

.Select will not do a join (which is what you want), use .Join or if it makes it easier, use the non-lambda way:

var query = (from m in db.Members
            join s in db.PlayTimeSchedules on m.Id equals s.MemberId
            select new { Id = m.Id, PlayTimeSchedules = s.DayOfWeek }).Distinct();
RPM1984
is it `from m in db.Members.Distinct()`? I get an error at `{ Id = m.Id.Distinct(),`
this does it in one trip, but surely ain't pretty: `db.Members.Distinct().Join(db.PlayTimeSchedules, m => m.Id, pts => pts.MemberId,(m, pts) => new { Id = m.Id, PlayTimeSchedules = pts.DayOfWeek }).ToList().GroupBy(item => item.Id, items => items.PlayTimeSchedules).Select(group => new { Id = group.Key, PlayTimeSchedules = group }).Take(20).ToList();`If I drop ToList before GroupBy - I end up with multiple trips. I wonder why.
see my edit with regards to DISTINCT, however it seems like your query is more complicated than we think. Can you pop the T-SQL you WANT to execute into LinqPad, and see what it tells you?
RPM1984
SQL I expect it to generate is exactly what your query produces. It returns lines of : Id, DayOfWeek. But now I need to repackage those into { Id, list of DayOfWeek } (every member's play schedule can be made of multiple days).
here is SQL I expect:`select distinct Members.Id, PlayTimeSchedule.DayOfWeek from Members join PlayTimeSchedule on PlayTimeSchedule.MemberId = Members.Id`
okay so its a one-many between Members and PlayTimeSchedule? It must be the distinct causing problems then. you might need two selects. if you pop the above SQL into LinqPad (your above comment), what LINQ query does it give you?
RPM1984
I don't know how to use linqpad to generate linq for given sql.
I don't think distinct is an issue, SQL returns exactly what I expect it to. Taking rows with repeating Id and building what I need is outside of SQL. It actually makes sense now.