Как отобразить идентичность объекта значения в EF6, используя свободный API? - PullRequest
0 голосов
/ 09 октября 2018

В DDD общепринятым является создание идентичности объекта как объекта значения.

Пример:

public class FooId : ValueObject  
{  
    public int Id { get; private set; }
}  

public class Foo
{  
    public FooId FooId { get; private set; }
}  

В EF6 я могу отображать типы, подобные этим, используя следующий код:

modelBuilder.ComplexType<SomeType>()
    .Property(x => x.SomeProperty)
    ...

(см. 3 Причины идентификации модели)как объект значения , IDDD )

Редактировать: IDDD в .Net

Но когда я пытаюсьчтобы отобразить Foo и FooId, я получаю следующую ошибку во время миграции

Недопустимое выражение свойств 'x => x.FooId.Id'.Выражение должно представлять свойство: C #: 't => t.MyProperty' VB.Net: 'Function (t) t.MyProperty'.При указании нескольких свойств используйте анонимный тип: C #: 't => new {t.MyProperty1, t.MyProperty2}' VB.Net: 'Function (t) New With {t.MyProperty1, t.MyProperty2}'.

Мои конфигурации:

public class FooConfiguration : EntityTypeConfiguration<Foo>
{  
    public FooConfiguration()
    {
        HasKey(x => x.FooId.Id);
    }
}  

public class FooContext : EntityTypeConfiguration<Foo>
{  
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.ComplexType<FooId>();
        modelBuilder.Configurations.Add(new FooConfiguration());
    }
}  

Используемые пакеты

  • EntityFramework 6.2.0
  • MySql.Data 6.10.7
  • MySql.Data.Entity 6.10.7

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

EF автоматически распознает сложные типы (объекты-значения), вам не нужно добавлять беглые отображения API.

Я даю вам пример из этого курса, Джули Лерман

Address - это ValueObject:

public class Address 
{
    public string Street { get; private set; }
    public string City { get; private set; }
    public string StateProvince { get; private set; }
    public string PostalCode { get; private set; }
}

SalesOrder - это наша сущность, которая использует Address сложный тип.

public class SalesOrder
{
    public int SalesOrderId { get; private set; }
    public DateTime OrderDate { get; private set; }
    public DateTime? DueDate { get; private set; }
    public string PurchaseOrderNumber { get; private set; }
    public string Comment { get; private set; }
    public Address ShippingAddress { get; private set; }
}

Теперь, если высначала используйте код EF для построения таблиц БД, вот что вы получите (код миграции):

CreateTable("SalesOrder", c => new
{
    SalesOrderId = c.Int(nullable: false),
    OrderDate = c.DateTime(nullable: false),
    DueDate = c.DateTime(),
    PurchaseOrderNumber = c.String(),
    Comment = c.String(),
    ShippingAddress_Street = c.String(),
    ShippingAddress_City = c.String(),
    ShippingAddress_StateProvince = c.String(),
    ShippingAddress_PostalCode = c.String(),
})
.PrimaryKey(t => t.SalesOrderId);

Обратите внимание, что EF непосредственно добавил все поля адреса в таблицу.

Выне требуется никаких дополнительных отображений API, позволяющих платформе сущностей добавлять Address поля в таблицу, приведенное выше поведение по умолчанию.

Вот как выглядит DbContext:

public class OrderContext: DbContext
{
    public OrderContext() : base("connectionStringName") { }
    DbSet<SalesOrder> Orders { get; set; }
}
0 голосов
/ 10 октября 2018

К сожалению, в настоящее время это невозможно в EF 6.x, и вам приходится иметь дело с обычными примитивами.Хотя это возможно в EF core 2.1 с использованием Преобразования значений .

В качестве альтернативы в классическом .Net Framework вы можете попробовать NHibernate, поскольку это позволяет иметь объект значения в качестве тождества.NHibernate все еще выглядит мощнее, чем EF с точки зрения Domain-Driven Design.

...