Alexandr Sulimov
Alexandr Sulimov

Reputation: 1924

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(); 

Upvotes: 9

Views: 26830

Answers (2)

Alexander Derck
Alexander Derck

Reputation: 14498

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(); 

Upvotes: 21

E-Bat
E-Bat

Reputation: 4892

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; }
    }

Upvotes: 1

Related Questions