在Entity Framework Core中使用[ComplexType]

Ser*_*rov 18 entity-framework-core asp.net-core-mvc

我在EF Core数据模型中使用了我自己的类的属性.

public class Currency
{
    public string Code { get; set; }
    public string Symbol { get; set; }
    public string Format { get; set; }
}

[ComplexType]
public class Money
{
    public int? CurrencyID { get; set; }
    public virtual Currency Currency { get; set; }
    public double? Amount { get; set; }
}

public class Rate
{
    public int ID { get; set; }
    public Money Price = new Money();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,当我尝试创建迁移时,EF Core报告错误.

Microsoft.Data.Entity.Metadata.ModelItemNotFoundException: The entity type 'RentABike.Models.Money' requires a key to be defined.
Run Code Online (Sandbox Code Playgroud)

如果我声明了一个键,就会创建一个单独的"Money"表,这不是我想要的.

有没有办法在EF Core中使用ComplexType并将它们全部放入一个表中?

Eri*_*kEJ 14

目前正在积压支持复杂类型https://github.com/aspnet/EntityFramework/issues/246

  • 它最终在EF Core 2.0中得到支持:https://docs.microsoft.com/en-us/ef/core/what-is-new/您必须使用一些流畅的API来配置它,但是还不支持注释. (4认同)
  • @SergeyKandaurov从EF Core 2.1开始,您现在可以使用`[Owned]`属性来表示拥有的类型. (4认同)
  • 这是支持还是我做错了什么?您是否必须使用fluentApi将对象声明为复杂的? (3认同)

Red*_*dog 9

作为基于上述评论之一的更新,现在OwnsOne您可以在DbContext OnModelCreating函数中使用Fluent API 使用此语法。

[ComplexType]
public class Money
{
    public double? Amount { get; set; }
}

public class Rate
{
    [Key]
    public long Id { get; set; }

    public Money Price { get; set; }
}

public MyDbContext : DbContext
{
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         modelBuilder.Entity<Rate>(entity =>
         {
             entity.OwnsOne(e => e.Currency);
         });
     }
}
Run Code Online (Sandbox Code Playgroud)

我实际上不确定它是否使用了ComplexTypeAttribute。但是,当我通过Add-Migration生成迁移时,它会以这种方式为旧的ComplexType文档生成预期的生成(即,名为table的表Rate具有column Price_Amount)。


Shi*_*mmy 5

Diego Vega宣布了Ownered Entities 和 Table Splitting,这应该是一种不同的方法和复杂类型的替代方案。

不能分享我的个人印象,因为我没有亲自检查过这个,但朱莉勒曼似乎已经很满意了......


pix*_*ker 5

用:

modelBuilder.Owned<T>: 
Run Code Online (Sandbox Code Playgroud)

例子:

public MyDbContext : DbContext
{
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         modelBuilder.Owned<Rate>();
     }
}
Run Code Online (Sandbox Code Playgroud)

  • 或者您可以简单地在实体类本身上添加 [Owned] 属性 (2认同)