如何使用fluent apiMapef6中的值对象标识?

vwoqyblh  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(448)

在ddd中,将实体的标识作为值对象是一种常见的设计。
例子:

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

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

在ef6中,我可以使用以下代码Map如下类型:

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

(请参阅将标识建模为值对象iddd的3个原因)
编辑:iddd in.net
但是当我尝试Mapfoo和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());
    }
}

使用的程序包
实体框架6.2.0
mysql.data 6.10.7版本
mysql.data.entity 6.10.7版本

iswrvxsc

iswrvxsc1#

不幸的是,目前这是不可能的 EF 6.x 你必须处理正则原语。虽然这是可能的 EF core 2.1 使用值转换。
作为经典的替代品 .Net Framework 你可以试试 NHibernate 因为它允许有值对象作为标识。 NHibernate 看起来还是比 EFDomain-Driven Design 观点。

zlwx9yxi

zlwx9yxi2#

ef自动识别复杂类型(值对象),您不需要添加任何fluent apiMap。
我给你举一个例子,来自这个课程,由朱莉勒曼 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代码来构建db表,您将得到以下结果(迁移代码):

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直接将所有地址字段添加到表中。
您不需要任何额外的fluent apiMap就可以让实体框架添加 `Address` 字段到表中,以上是默认行为。
这就是 `DbContext` 看起来像:

public class OrderContext: DbContext
{
public OrderContext() : base("connectionStringName") { }
DbSet Orders { get; set; }
}

相关问题