Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq EF Include() with Select() new type lost included

context.Projects
.Include(x => x.Members) //List<Member> public class Member
.Include(x => x.Members.Select(z => z.City)) //public class City
.ToList(); 

Select from Projects

include list of project.Members

include each of project.Members.City

Need add some data to result

context.Projects
.Include(x => x.Members) 
.Include(x => x.Members.Select(z => z.City)) 
.Select(x => new {
    Project = x,
    Amount = 22
})
.ToList(); 

Project properties is filled but Members is null

Question 1 - how include Project.Members with new { Project = x }

I do next

context.Projects
.Include(x => x.Members) //List<Member>
.Include(x => x.Members.Select(z => z.City)) //City is navigation property
.Select(x => new {
    Project = x,
    Members = x.Members,
    Amount = 22
})
.ToList(); 

Project properties is filled and Members is filled but Members[0].City is null

Question 2 - how fill Members[0].City

P.S.

EntityFramework 6

public class Project
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<ProjectMember> Members { get; set; }
}

public class ProjectMember
{
    public Guid ProjectId { get; set; }
    public Project Project { get; set; }

    public Guid CityId { get; set; }
    public City City { get; set; }
}

P.S.S

This work - but code overhead

context.Projects
.Include(x => x.Members) //List<Member>
.Include(x => x.Members.Select(z => z.City)) //City is navigation property
.Select(x => new {
    Project = x,
    Members = x.Members.Select(z => new {
        Item = z,
        City= z.City
    }).ToList(),
    Amount = 22
})
.ToList(); 
like image 523
Alexandr Sulimov Avatar asked Mar 17 '16 21:03

Alexandr Sulimov


2 Answers

Any operations you do after the includes (except for filtering) will cause the includes to be discarded. By calling AsEnumerable after the includes, you will make sure the query gets executed then and the rest of the operations will be done in memory:

context.Projects 
       .Include(x => x.Members) 
       .Include(x => x.Members.Select(z => z.City))
       .AsEnumerable() 
       .Select(x => new { Project = x, Amount = 22 }) 
       .ToList(); 
like image 87
Alexander Derck Avatar answered Sep 21 '22 21:09

Alexander Derck


Declare your navigation properties as virtual,list as ICollection, and let EF replace with its concrete implementation when hydrating your entities:

public class Project
    {
        public Project { 
            Members = new HashSet<ProjectMember>(); 
        }
        public Guid Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<ProjectMember> Members { get; set; }
    }

    public class ProjectMember
    {
        public Guid ProjectId { get; set; }
        public virtual Project Project { get; set; }

        public Guid CityId { get; set; }
        public virtual City City { get; set; }
    }
like image 32
E-Bat Avatar answered Sep 20 '22 21:09

E-Bat