简体   繁体   English

EF Core 3.0中的拥有类型映射问题

[英]Problem with owned types mapping in EF Core 3.0

I've migrated from EF Core Preview5 to Preview7 and now I have same internal complex properties mapping through select. 我已经从EF Core Preview5迁移到Preview7,现在通过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) . 之前,代码modelBuilder.Entity<Car>().OwnsOne(e => e.Volume)正常工作,但是现在它需要使用WithOwner但我不明白(请参阅此处: httpsWithOwner 。 com / zh-CN / ef / core / what-is-new / ef-core-3.0 / breaking-changes )我不能使用这样的代码: modelBuilder.Entity<Car>().OwnsOne(e => e.Volume).WithOwner("Car")modelBuilder.Entity<Car>().OwnsOne(e => e.Volume).WithOwner(f => f.Car) Does anyone have the same problem? 有人有同样的问题吗?

Thanks. 谢谢。

Update. 更新。

I've checked OrderStoreDbContextModelSnapshot.cs. 我已经检查了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). 因此,正如我们所看到的,ContextSnapshot可以正确地映射数据(在这种情况下,实验上,ComplexType属性实际上没有执行任何操作)。

OrderStoreDbContext has public DbSet<OrderProfile> OrderProfiles { get; set; } OrderStoreDbContext具有public DbSet<OrderProfile> OrderProfiles { get; set; } public DbSet<OrderProfile> OrderProfiles { get; set; } public DbSet<OrderProfile> OrderProfiles { get; set; } property. public DbSet<OrderProfile> OrderProfiles { get; set; }属性。

But linq request var orderProfiles = await orderDbContext.OrderProfiles.ToListAsync(); 但是linq请求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 . 映射仅简单类型(存在于OrderProfiles表中,但不复杂var orderProfiles = await orderDbContext.OrderProfiles.Include(p => p.Volume).ToListAsync();代码也无效-我得到orderProfiles.Volume并将orderProfiles.StartPointorderProfiles.EndPoint值设置为null

But, in the Preview5 this code works fine. 但是,在Preview5中,此代码可以正常工作。 Has microsoft developers broken complex type mapping in EF Core 3.0 Preview7 or the problem in my curved hands? 微软开发人员是否破坏了EF Core 3.0 Preview7中的复杂类型映射,或者是我弯腰的问题?

Update 2. Posted an issue on github project repo. 更新2.在github项目仓库上发布了一个问题。

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)). WithOwner fluent API仍未记录(对于预览软件而言是正常的),但是它遵循关系API( HasOne / HasMany / WithOneWithMany )的导航属性模式-如果您具有导航属性,则可以传递lambda表达式或属性名称(串))。 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: 您可以看到使用“转到定义”命令的WithOwner重载之一是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. VS Intellisense显示相同。

So in your case, just use WithOwner() , eg 因此,在您的情况下,只需使用WithOwner() ,例如

modelBuilder.Entity<Car>().OwnsOne(e => e.Volume).WithOwner()
    . /* configuration goes here */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM