【问题标题】:Using [ComplexType] in Entity Framework Core在 Entity Framework Core 中使用 [ComplexType]
【发布时间】:2015-08-09 17:32:47
【问题描述】:

我在 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();
}

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

Microsoft.Data.Entity.Metadata.ModelItemNotFoundException: The entity type 'RentABike.Models.Money' requires a key to be defined.

如果我声明一个键,则会为“Money”创建一个单独的表,这不是我想要的。

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

【问题讨论】:

    标签: asp.net-core-mvc entity-framework-core


    【解决方案1】:

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

    【讨论】:

    • 这是支持还是我做错了什么?是否必须使用 fluentApi 将对象声明为复杂对象?
    • EF Core 2.0 终于支持了:docs.microsoft.com/en-us/ef/core/what-is-new 不过你得使用一些 fluent API 来配置它,目前还不支持注解。
    • @SergeyKandaurov 从 EF Core 2.1 开始,您现在可以使用 [Owned] 属性来表示拥有的类型。
    【解决方案2】:

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

    [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);
             });
         }
    }
    

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

    【讨论】:

      【解决方案3】:

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

      无法分享我的个人印象,因为我没有亲自检查过,但是Julie Lermanseems to have been satisfied...

      【讨论】:

        【解决方案4】:

        用途:

        modelBuilder.Owned<T>: 
        

        例子:

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

        【讨论】:

        • 或者您可以简单地在实体类本身上添加 [Owned] 属性
        【解决方案5】:

        你可以把[NotMapped]放在上面

        public class Rate
        {
            public int ID { get; set; }
            [NotMapped]
            public Money Price = new Money();
        }
        

        像这样。

        【讨论】:

        • 这个不会放到db里
        • @SergeyKandaurov 是的,因为 Money 类没有任何主键值,所以它不是实体..如果它不是实体,那么它不会映射到 db ..但是你可以使用它在外部,但不会将其值存储在 db 中
        猜你喜欢
        • 2017-09-30
        • 2020-09-14
        • 1970-01-01
        • 2016-06-30
        • 2016-06-30
        • 1970-01-01
        • 2022-12-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多