Configuring navigations through owned types in EF Core

226 Views Asked by At

Ask a question

My goal is to create a value object as an owned type, and to configure the relationship of the owner to another table through this valueobject.

So in my case I have a Person, and a Person has a PhoneNumber. A PhoneNumber is a string column and an int column, where the int column is a foreign key to a Country table.

I want my Person to look like this

public class Person 
{
    public int Id { get; set; }
    public PhoneNumber Phone { get; set; }
}

And my Phone class is like this:

public class PhoneNumber : ValueObject
{
    public Country Country { get; set; }
    public string Number { get; set; }
}

Country is just any table.

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
}

I have configured Person like this:

   builder.OwnsOne(o => o.Phone, options =>
        {
            options.Property(p => p.Number).HasColumnName($"PhoneNumber");
            options.HasOne(x => x.Country)
                .WithMany()
                .HasForeignKey($"PhoneCountryId")
                .OnDelete(DeleteBehavior.NoAction)
                .IsRequired(true);
        
            options.Property($"PhoneCountryId")
                .HasColumnName($"PhoneCountryId");
        
            options.Property($"PhoneCountryId")
                .IsRequired()
                .HasDefaultValue(1);
        
            options.WithOwner();
        });

I am configuring the actual foreign key to Country with strings here, because I dont want to put it explicitly in my class.

Desired database structure is:

Person Another header
Id int
PhoneCountryId int (country FK)
PhoneNumber string
Country Another header
Id int
Name string

When I try to project/select this object from my Person table, the Country navigation is not populated.

Example:

dbContext.Persons.Select(x => x.Country.Name);

If I add options.Navigation(e => e.Country).AutoInclude(); to my config, it is populated, but I need to use ".AsNoTracking()" to my query, or else I get this error: "A tracking query is attempting to project an owned entity without a corresponding owner in its result, but owned entities cannot be tracked without their owner. Either include the owner entity in the result or make the query non-tracking using 'AsNoTracking'."

This leads me to believe that the relationship is not properly configured. It's able to determine that when I select Person.Phone.Country I get the correct country, but appearntly not that Country is owned by Person?

Include provider and version information

EF Core version: 7.0.2 Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer) Target framework: (e.g. .NET 7.0) Operating system: Linux IDE: Rider

1

There are 1 best solutions below

0
oysandvik On

Error was actually due to a method call in a mapper that could not be translated, and not due to EF Core config.