Search code examples
linqentity-framework-corefluent

Fluent LINQ EF Core - Select filtered child property


I have the classes below:

  public class User
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }

    public class ParentEntity
    {
        public Guid Id { get; set; }

        public string SomeProperty { get; set; }

        public ICollection<ChildEntity> ChildEntities { get; set; }

    }

    public class ChildEntity
    {
        public Guid Id { get; set; }

        public int Vote { get; set; }

        public Guid UserId { get; set; }
    }

    public class ReturnedParentDto
    {
        public Guid Id { get; set; }
        public string SomeProperty { get; set; }
        public int Vote { get; set; }

    }

I want to be able to return a full list of ParenEntities, but take an Id of the User class (UserClassId), then filter the ParentEntity's ICollection where UserUid = UserClassId, so only 1 ChildEntity is always returned. Then I would want to extract a specific field from that returned ChildEntity and merge it with the ParentEntity fields. The end result should be like the ReturnedParentDto.

I want to do it in the style like

ParentEntities.Include(v => v.ChildEntities).ToList()

That seems to be possible in EF Core 5, but my project is in 3.1.


Solution

  • You can do this as below

    Approach 1:

    var result = result = parentEntities.Include(x => x.ChildEntities.Where(y => y.UserId == userId))
         .Select(x => new ReturnedParentDto {
              Id = x.Id,
              SomeProperty = x.SomeProperty,
              Vote = x.ChildEntities.FirstOrDefault()?.Vote // userId is the variable here
         });
    

    Approach 2:

    var result = parentEntities.Select(x => 
      new ReturnedParentDto {
          Id = x.Id,
          SomeProperty = x.SomeProperty,
          Vote = x.ChildEntities.FirstOrDefault(y => y.UserId == userId)?.Vote // userId is the variable here
     });