Home > Enterprise >  EF Core query and projection to dto doesn't fill the property
EF Core query and projection to dto doesn't fill the property

Time:02-01

How to write EF Core query to fill the properties in certain order?

public record PersonDto : BaseDto //Id is Guid
{
    public string Firstname { get; init; }
    public string Lastname { get; init; }

    public DateOnly Birthday { get; init; }

    public IReadOnlyCollection<Guid> AddressesIds { get; init; }

    public Guid? MainAddressId { get; init; }
}

internal class Person : SoftDeletableEntity //Id is Guid
{
    public Person()
    {
        Addresses = new HashSet<Address>();
        Emails = new HashSet<Email>();
        PhoneNumbers = new HashSet<PhoneNumber>();
    }

    public string Firstname { get; set; }
    public string Lastname { get; set; }

    public DateOnly Birthday { get; set; }

    public ICollection<Address> Addresses { get; set; }

    public Guid? MainAddressId => MainAddress?.Id;

    public Address? MainAddress => Addresses.Where(adr => adr.IsPrimary).FirstOrDefault();
}

internal sealed partial class Context : DbContext
{
    public DbSet<Person> People => Set<Person>();
}

var context = new Context();
var peopleQuery = context.People
    .Skip(10)
    .Take(10)
    .Select(p=> new PersonDto(){
    AddressesIds = new HashSet<Guid>(p.Addresses.Select(a => a.Id).Where(a => a.IsPrimary),
    MainAddressId = p.MainAddressId,
    //bla bla 
};
var peopleResult = people.ToList();

At the end of this fragment, peopleResult has all the addresses ids have been loaded, but the MainAddressId of the dto is null.

When I debug the code, MainAddressId is called before populate the list of Addresses, how I change this, or how is this supposed to be done if I'm doing it wrong.

Thanks in advance.

CodePudding user response:

Do you really need MainAddressId and MainAddress properties of the Person. As I understand you have these in the Address model? You can just do the select like this:

var peopleQuery = context.People
    .Skip(10)
    .Take(10)
    .Select(p=> new PersonDto(){
    AddressesIds = new HashSet<Guid>(p.Addresses.Select(a=> a.Id),
    MainAddressId = p.Addresses.FirstOrDefault(a=> a.IsPrimary),
};
var peopleResult = people.ToList();

You need only the Addresses, then you can easily filter which is the main one, and assign it to the DTO's property.

CodePudding user response:

I Think the problem is that calculated properties in your entity. I had a similar problem a few months ago. I just removed that properties from my Entity an put it in my DTOs.

  • Related