在 Entity Framework Core 中使用 [ComplexType]

Posted

技术标签:

【中文标题】在 Entity Framework Core 中使用 [ComplexType]【英文标题】:Using [ComplexType] in Entity Framework Core 【发布时间】: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 并将其全部放入一个表中?

【问题讨论】:

【参考方案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 Lerman、seems 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 中

以上是关于在 Entity Framework Core 中使用 [ComplexType]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Entity Framework Core 中运行存储过程?

如何在 Entity Framework Core 中运行存储过程?

什么是自有实体?何时以及为什么在 Entity Framework Core 中使用 Owned Entity?

Entity Framework Core 中 TimeSpan 的总和

Entity Framework优化一:引发了“System.Data.Entity.Core.EntityCommandExecutionException”类型的异常

如何在 Entity Framework Core 2 中播种?