Использование [ComplexType] в Entity Framework Core

Я использую свойство собственного класса внутри модели данных 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.

Если я объявляю ключ, создается отдельная таблица для «Деньги», а это не то, что я ищу.

Есть ли способ использовать ComplexType в EF Core и поместить все это в одну таблицу?


person Sergey Kandaurov    schedule 09.08.2015    source источник


Ответы (5)


Поддержка сложных типов в настоящее время находится в очереди https://github.com/aspnet/EntityFramework/issues/ 246

person ErikEJ    schedule 09.08.2015
comment
Это уже поддерживается или я что-то не так делаю? Вам нужно объявить объект сложным, используя fluentApi? - person Gillardo; 07.01.2016
comment
Наконец, он поддерживается в EF Core 2.0: docs.microsoft.com. /en-us/ef/core/what-is-new Для его настройки необходимо использовать некоторый свободный API, аннотации пока не поддерживаются. - person Sergey Kandaurov; 23.12.2017
comment
@SergeyKandaurov Начиная с EF Core 2.1, теперь вы можете использовать атрибут [Owned] для обозначения принадлежащих типов. - person saluce; 05.06.2018

В качестве обновления, основанного на одном из ваших комментариев выше, вы теперь используете синтаксис OwnsOne для этого, используя Fluent API в вашей функции OnModelCreating DbContext.

[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).

person Reddog    schedule 07.03.2018

Диего Вега объявил Owned Entities and Table Splitting, который должен быть другим подходом и альтернатива сложным типам.

Не могу поделиться своими личными впечатлениями, потому что я не проверял это лично, но Julie Lerman, кажется удовлетворенным...

person Shimmy Weitzhandler    schedule 19.08.2017

Использовать:

modelBuilder.Owned<T>: 

Пример:

public MyDbContext : DbContext
{
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         modelBuilder.Owned<Rate>();
     }
}
person pixparker    schedule 23.01.2019
comment
или вы можете просто добавить атрибут [Owned] в сам класс сущности - person ctorx; 18.06.2019

Вы можете просто поставить [NotMapped] выше

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

как это.

person Asif Khan    schedule 21.12.2017
comment
Это не поместит его в БД - person Sergey Kandaurov; 23.12.2017
comment
@SergeyKandaurov да, поскольку класс Money не имеет значения первичного ключа, поэтому он не является сущностью ... и если, если это не сущность, то он не будет сопоставлен с БД ... но вы можете использовать его извне, но значение этого не будет хранится в БД - person Asif Khan; 25.12.2017