Search code examples
entity-frameworklambdaasp.net-core-mvcentity-framework-6

Entity framework 6 join on a groupjoin using lambda


I need to set a Join on an GroupJoin. I have googled a lot to find the answer on my problem, but i cannot find it.

In the database I have templates. I select a template with a table joined to that with items. There is also a table with one or multiple rows with files linked to the item, that is the GroupJoin I use. That one works, but now the problem is, that I need to call the table (and that is always 1 not more) that is linked to table with files.

So far I have this with a join in the groupjoin, but that join isn't working at all:

DataBundle = _context.DataTemplates.Join(_context.DataItems, DataTemplates                        => DataTemplates.Id, DataItems => DataItems.DataTemplateId, (DataTemplates, DataItems) => new { DataTemplates, DataItems })
                               .GroupJoin(_context.DataItemFiles.Join(_context.DataTemplateUploads, DataItemFiles => DataItemFiles.DataTemplateUploadId, DataTemplateUploads => DataTemplateUploads.Id, (DataItemFiles, DataTemplateUploads) => new { DataItemFiles, DataTemplateUploads }), x => x.DataItems.Id, x => x.DataItemFiles.DataItemId, (x, DataItemFiles) => new { x.DataItems, x.DataTemplates, DataItemFiles })
                               .Where(x => x.DataTemplates.CallName == CallName).Where(x => x.DataItems.WebsiteLanguageId == WebsiteLanguageId)
                               .Select(x => new DataBundle()
                               {
                                   DataItemFiles = x.DataItemFiles, //error
                                   DataItemResources = null,
                                   DataItems = x.DataItems,
                                   DataTemplateFields = null,
                                   DataTemplates = x.DataTemplates,
                                   DataTemplateUploads = x.DataTemplateUploads, //can't find, because DataTemplateUploads is linked to DataItemFiles
                               }).ToList();

public class DataBundle
{
    public IEnumerable<DataItemFiles> DataItemFiles { get; set; }
    public IEnumerable<DataItemResources> DataItemResources { get; set; }
    public DataItems DataItems { get; set; }
    public IEnumerable<DataTemplateFields> DataTemplateFields { get; set; }
    public DataTemplates DataTemplates { get; set; }
    public IEnumerable<DataTemplateUploads> DataTemplateUploads { get; set; }
}

Someone know how to solve this?


Solution

  • The DataItemFiles variable here

    (x, DataItemFiles) => new { x.DataItems, x.DataTemplates, DataItemFiles }
    

    is actually IEnumerable<anonymous_type> where anonymous_type is the result of the previous Join operator new { DataItemFiles, DataTemplateUploads } (btw, you should use singular form for most of the names, it's really hard to follow which one is single and which one is sequence).

    Hence to get the individual parts you need to use projection (Select):

    .Select(x => new DataBundle()
    {
        DataItemFiles = x.DataItemFiles.Select(y => y.DataItemFiles),
        // ...
        DataTemplateUploads = x.DataItemFiles.Select(y => y.DataTemplateUploads),
        // ...
    }