Entity Framework lambda with include return empty collection

2

I have a select that returns chained data and plays them in a ViewModel created for the simple reason that I can not return all the data in my table, as in the example:

var data = _context.Forms
.Include(i => i.OrganizationUnit)
.Include(i => i.FormSections)
.Include(i => i.FormSections.Select(p => p.Predecessors))
.Include(i => i.FormSections.Select(p => p.FormSectionSecurities))
.Include(i => i.FormSections.Select(p => p.FormSectionSecurities.Select(x => x.FormSectionSecurityPremission)))
.Include(i => i.FormSections.Select(p => p.FormSectionSecurities.Select(x => x.Role)))
.Include(i => i.FormSections.Select(p => p.FormSectionFields))
.Include(i => i.FormSections.Select(p => p.FormSectionFields.Select(x => x.FormSectionFieldType)))
.Include(i => i.FormSections.Select(p => p.FormSectionFields.Select(x => x.FormSectionFieldType)))
.Include(i => i.FormSections.Select(p => p.FormSectionFields.Select(x => x.List)))
.Include(i => i.FormSections.Select(p => p.FormSectionFields.Select(x => x.List).Select(j => j.ListItems)))
.OrderBy(i => i.Name)
.AsNoTracking()
.Where(i => i.EFormStatus == EFormStatus.Active)
.Select(f => new FormViewModel
{
    Id = f.Id,
    Name = f.Name,
    Description = f.Description,
    EFormStatus = f.EFormStatus,
    Instructions = string.Empty,
    OrganizationUnit = f.OrganizationUnit,
    FormSections = f.FormSections
}).ToList();

f.FormSection returns a collection that has more collections inside, as you can see for Includes , for example: FormSectionFields . The problem occurs precisely in the return of this "third level" that comes empty, even with the includes. It also occurs for any collection that is below the f.FormSection collection.

Any indication of what to do or what may be wrong?

Below FormViewModel

public class FormViewModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public OrganizationUnit OrganizationUnit { get; set; }
    public string Description { get; set; }
    public string Instructions { get; set; }
    public EFormStatus EFormStatus { get; set; }
    public ICollection FormSections { get; set; }  
}

UPDATED

I discard the use of joins using Linq (query syntax), since it is necessary that only one row is returned with the chained objects.

    
asked by anonymous 14.02.2018 / 23:52

1 answer

2

You can create multiple selects including your tables as follows.

var data = _context.Forms
.Select(f => new 
{
  Forms = f.Forms,
  OrganizationUnit = _context.OrganizationUnit.FirstOrDefault(x => x.OrganizationUnitId == f.OrganizationUnitId) // Todo seus ids ... x.OrganizationUnitId == f.OrganizationUnitId
  FormSections = _context.FormSections.Where(x => x.FormSectionsId == f.FormSectionsId) // Todo seus ids ...x.FormSectionsId == f.FormSectionsId  
})
.Select(f => new 
{
   Forms = f.Forms,
   OrganizationUnit = f.OrganizationUnit,
   f.FormSections.Predecessors = _context.Predecessors.Where(x => x.PredecessorsId == f.FormSectionsId) 
   FormSections = f.FormSections,
   // ....  demais campos
})
.AsNoTracking()
.Where(i => i.EFormStatus == EFormStatus.Active)
.Select(f => new FormViewModel
{
    Id = f.Forms.Id,
    Name = f.Forms.Name,
    Description = f.Forms.Description,
    EFormStatus = f.EFormStatus,
    OrganizationUnit = f.OrganizationUnit,
    FormSections = f.FormSections
}).ToList();

In the end this becomes a single select with JOIN, a problem that may occur in your case is that if there is no relationship between your tables, the properties of your FormViewModel will be null.

For example, if there is no relationship between FormSections and Form the return of the property below will be null .

FormSections = _context.FormSections.Where(x => x.FormSectionsId == f.FormSectionsId)
    
15.02.2018 / 12:52