Problem with owned types mapping in EF Core 3.0

.net-core c# ef-core-3.0 entity-framework-core

Question

I've migrated from EF Core Preview5 to Preview7 and now I have same internal complex properties mapping through select.

For example:

public class Car
{
    public Volume Volume { get; set; }
    public string OtherProperty { get; set; }
}

[Owned]
public class Volume
{
    public float Height { get; set; }
    public float Width { get; set; }
    public float Length { get; set;}
}

Earlier, the code modelBuilder.Entity<Car>().OwnsOne(e => e.Volume) worked properly, but now it needs to use WithOwner but I can't understand (see here: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes) I can't use code like this: modelBuilder.Entity<Car>().OwnsOne(e => e.Volume).WithOwner("Car") or modelBuilder.Entity<Car>().OwnsOne(e => e.Volume).WithOwner(f => f.Car). Does anyone have the same problem?

Thanks.

Update.

I've checked OrderStoreDbContextModelSnapshot.cs. I've posted here other example fully congruent with the upper example.

modelBuilder.Entity("DatabaseServiceNew.Database.Order_information.OrderProfile", b =>
            {
                b.HasOne("DatabaseService.Database.Order_information.Order", "Order")
                    .WithOne("OrderProfile")
                    .HasForeignKey("DatabaseServiceNew.Database.Order_information.OrderProfile", "OrderId")
                    .OnDelete(DeleteBehavior.Cascade)
                    .IsRequired();

                b.OwnsOne("FoundationClasses.Technical_Classes.Volume", "Volume", b1 =>
                    {
                        b1.Property<Guid>("OrderProfileId");

                        b1.Property<float>("Cum");

                        b1.Property<float>("Height");

                        b1.Property<float>("Length");

                        b1.Property<float>("Width");

                        b1.HasKey("OrderProfileId");

                        b1.ToTable("OrderProfiles");

                        b1.WithOwner()
                            .HasForeignKey("OrderProfileId");
                    });

                b.OwnsOne("WebFoundationClassesCore.Data_classes.GeoPoint", "EndPoint", b1 =>
                    {
                        b1.Property<Guid>("OrderProfileId");

                        b1.Property<string>("Address");

                        b1.Property<double>("Latitude");

                        b1.Property<double>("Longitude");

                        b1.HasKey("OrderProfileId");

                        b1.ToTable("OrderProfiles");

                        b1.WithOwner()
                            .HasForeignKey("OrderProfileId");
                    });

                b.OwnsOne("WebFoundationClassesCore.Data_classes.GeoPoint", "StartPoint", b1 =>
                    {
                        b1.Property<Guid>("OrderProfileId");

                        b1.Property<string>("Address");

                        b1.Property<double>("Latitude");

                        b1.Property<double>("Longitude");

                        b1.HasKey("OrderProfileId");

                        b1.ToTable("OrderProfiles");

                        b1.WithOwner()
                            .HasForeignKey("OrderProfileId");
                    });
            });

where

[Owned, ComplexType]
public class Volume
{
    public float Height { get; set; }
    public float Width { get; set; }
    public float Length { get; set;}
}


[Owned, ComplexType]
public class GeoPoint 
{
    public GeoPoint() 
    {
    }
    public GeoPoint(double latitude, double longitude, string address) 
    {
        this.Address = address;
        this.Latitude = latitude;
        this.Longitude = longitude;
    }

    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public string Address { get; set;}
}

So, as we can see, ContextSnapshot maps data correctly (ComplexType attribute do nothing in real in this case, experimentally).

OrderStoreDbContext has public DbSet<OrderProfile> OrderProfiles { get; set; } property.

But linq request var orderProfiles = await orderDbContext.OrderProfiles.ToListAsync(); maps just simple types (which are exist in the OrderProfiles table, but not complex. var orderProfiles = await orderDbContext.OrderProfiles.Include(p => p.Volume).ToListAsync(); code also has no effect - I get orderProfiles.Volume and orderProfiles.StartPoint and orderProfiles.EndPoint values as null.

But, in the Preview5 this code works fine. Has microsoft developers broken complex type mapping in EF Core 3.0 Preview7 or the problem in my curved hands?

Update 2. Posted an issue on github project repo.

1
3
7/26/2019 2:43:54 PM

Accepted Answer

WithOwner fluent API is still undocumented (normal for preview software), but it follows the relationship API (HasOne / HasMany / WithOne, WithMany) pattern for navigation property - if you have navigation property, pass either lambda expression or the name of the property (string)). If you don't have navigation property, don't pass anything.

You can see that for one of the WithOwner overloads using Go To Definition Command is VS:

//
// Summary:
//     Configures the relationship to the owner.
//     Note that calling this method with no parameters will explicitly configure this
//     side of the relationship to use no navigation property, even if such a property
//     exists on the entity type. If the navigation property is to be used, then it
//     must be specified.
//
// Parameters:
//   ownerReference:
//     The name of the reference navigation property pointing to the owner. If null
//     or not specified, there is no navigation property pointing to the owner.
//
// Returns:
//     An object that can be used to configure the relationship.
public virtual OwnershipBuilder<TEntity, TDependentEntity> WithOwner([CanBeNullAttribute] string ownerReference = null);

Same is shown by VS Intellisense.

So in your case, just use WithOwner(), e.g.

modelBuilder.Entity<Car>().OwnsOne(e => e.Volume).WithOwner()
    . /* configuration goes here */
3
7/26/2019 12:37:25 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow