3.11.- ‘Fluent API’和领域实体
我们应该使用代码优先‘Fluent API’来改变/自定义实体映射,然而,它必须重写DbContext方法。
特别地,我们必须重写”DbContext OnModelCreating()‟方法。这是数据持久化层的部分,所以我们
会在那章中解释如何使用。
关于领域驱动设计和持久化透明原则的重要主要事项:
“数据注解”开始看起来简单易用,但是从持久化透明的原则看,由于需要引入一些持久化的属性,
而这对于领域实体不利。
另一方面,使用“默认协定”或“Fluent API‟更好的适合持久化透明,因为我们的领域模型对映射
完全无知,这样我们的领域模型层会更好的与基础设计实现隔离。
因此,如果你从头开始你的项目,最好的方法大概是这样:”尽量让实体类使用默认协定“,这样
你的POCO领域实体会更干净。另外,使用”Fluent API‟或实现你自己的验证不会污染你的领域实体。
3.12.- 不需要映射的实体属性
有时当我们创建领域实体模型时,我们需要有一些属性不被关联/映射到数据库的列。
当使用模型/数据库优先(EDMX)或T4模板代码生成器时,我们可以使用部分类。现在我们有一个更好
的解决方法。
数据注解的“NotMappedAttribute‟属性指定了不希望映射的属性。下面的代码展示了该项。
//Using ‘NotMappedAttribute’ Data Annotation
//
public class Customer : Entity
{
//Omitted for brevity
public string FirstName { get; set; }
public string LastName { get; set; }
[NotMapped()]
public string FullName
{
get
{
return string.Format("{0}, {1}", this.LastName, this.FirstName);
}
}
}
当我们想用”Fluent API‟时,我们可以用“„Ignore()"方法,如下所示。
//Using ‘Ignore()’ method Fluent API – (Code in Data Persistence Infr.Layer)
//
protected override void OnModelCreating(DbModelBuilder modelBulder)
{
modelBuilder.Entity<Customer>()
.Ignore(c => c.FullName);
}
考虑到使用”Fluent API‟的“OnModelCreating()"方法位于数据持久化层,我们不在本章中过多介绍。
3.13.- 只读的实体属性
这个特性看起来是很简单的概念,但其实不是。当我们指只读属性时,该属性是在领域模型内部计算过,
不是从外部的"Set”赋值。该属性也是存在数据库中。
你可以看到下面的代码可以实现一个只读的属性也是存在数据库中。
//Wrong Code-First Read-Only property
//
public class Customer : Entity
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
return string.Format("{0}, {1}", this.LastName, this.FirstName);
}
}
}
这段代码是不正确的。实际上这个属性不会存在数据库中。我们只要添加一个空的"set"方法就可以实现。
//Using ‘NotMappedAttribute’ Data Annotation
//
public class Customer : Entity
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
return string.Format("{0}, {1}", this.LastName, this.FirstName);
}
set { }
}
}
这么多该只读属性就会存到数据库中。
// Example of a Navigation Property ready for Proxy
public class BankAccount : Entity
{
//... Ommitted ...
public virtual ICollection<BankTransferLog> TransfersHistory { get; set; }
//... Ommitted ...
}