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.
Entity Framework (EF) Core, Microsoft's object-to-database mapper library for . NET Framework, brings performance improvements for data updates in version 7, Microsoft claims. The performance of SaveChanges method in EF7 is up to 74% faster than in EF6, in some scenarios.
Keep using EF6 if the data access code is stable and not likely to evolve or need new features. Port to EF Core if the data access code is evolving or if the app needs new features only available in EF Core. Porting to EF Core is also often done for performance.
EF Core does not support the EDMX file format for models. The best option to port these models, is to generate a new code-based model from the database for your application.
Owned entities are essentially a part of the owner and cannot exist without it, they are conceptually similar to aggregates. This means that the owned entity is by definition on the dependent side of the relationship with the owner.
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 */
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With