views:

18

answers:

1

The following LINQ:

retval = ( from jm in entities.JobMasters
                 where jm.UserId == userId && jm.IsRemote == false
                 select new JobDto
                 {
                     JobMasterId = jm.JobMasterId,
                     ExternalTaskId = jm.ExternalTaskId,
                     JobDetails = ( from jd in entities.JobDetails
                                    where jd.JobMasterId == jm.JobMasterId
                                    select new JobDetailDto { ScreenFieldId = jd.ScreenFieldId, FieldValue = jd.FieldValue }
                     ).ToList()
                 }
            ).ToList();

is giving me this error:

LINQ to Entities does not recognize the method 'System.Collections.Generic.List1[KernWcfTest.DataTransferObjects.JobDetailDto] ToList[JobDetailDto](System.Collections.Generic.IEnumerable1[KernWcfTest.DataTransferObjects.JobDetailDto])' method, and this method cannot be translated into a store expression.

Here are the two dto classes:

[DataContract]
public class JobDetailDto
{
    [DataMember]
    public int ScreenFieldId { get; set; }

    [DataMember]
    public string FieldValue { get; set; }
}

[DataContract]
[KnownType(typeof(JobDetailDto))]
public class JobDto
{
    [DataMember]
    public int JobMasterId { get; set; }

    [DataMember]
    public string ExternalTaskId { get; set; }

    [DataMember]
    public List<JobDetailDto> JobDetails { get; set; }
}

The problem is the sub-select and the JobDetails list. I tried adding the KnownType but it didn't work.

This all works fine in LINQ Pad.

Any ideas?

Cheers

Steve

+1  A: 

Don't call ToList on the inner query (the one for JobDetails). The error is "This .ToList method you speak of -- it can't be translated to T-SQL!"

This should work:

retval = ( from jm in entities.JobMasters
             where jm.UserId == userId && jm.IsRemote == false
             select new JobDto
             {
                 JobMasterId = jm.JobMasterId,
                 ExternalTaskId = jm.ExternalTaskId,
                 JobDetails =   from jd in entities.JobDetails
                                where jd.JobMasterId == jm.JobMasterId
                                select new JobDetailDto { ScreenFieldId = jd.ScreenFieldId, FieldValue = jd.FieldValue }
                 )
             }
        ).ToList();

Note that you can call ToList on the end of the query, as that part doesn't need to be translated to T-SQL.

Judah Himango
I think you are heading in the right direction, but that gives me Cannot implicitly convert type 'System.Linq.IQueryable<KernWcfTest.DataTransferObjects.JobDetailDto>' to System.Collections.Generic.List<KernWcfTest.DataTransferObjects.JobDetailDto>'.
SteveChadbourne
What error do you get (if any) if you change the last .ToList() to .AsEnumerable().ToList()?
Martin Booth
The problem now is that your DTO doesn't map well to your queries. Let your DTO accept an IEnumerable<T>, or do separate queries.
Judah Himango
Changed DTO to accept IEmumerable<T> and all now works. Thanks Judah.
SteveChadbourne
Martin - tried your suggestion but didn't work. Same error as in original question.
SteveChadbourne