[英]What are the disadvantages to inheriting Persistence Models from Domain Models to save mapping effort using Entity Framework?
我一直在考慮從原始域模型(DM)類繼承我的持久性模型(PM),以便添加一些對持久性邏輯很重要的屬性。 這樣,我將不必處理很多映射代碼。
為了簡單起見,這里是一個表示信用的DM,用戶或組織可以用來下訂單。
namespace Foo.Domain
{
// Domain Model
public class Credit : IDomainEntity, IAggregateRoot
{
public Credit(int? userId, int? organizationId, DateTime expiryDate)
{
if(userId == null && organizationId == null)
throw new InvalidOperationException("MUST assign credit to user OR organization.");
if(userId != null && organizationId != null)
throw new InvalidOperationException("CANNOT assign credit to user AND organization.");
UserId = userId;
OrganizationId = organizationId;
ExpiryDate = expiryDate;
}
public virtual int Id { get; private set; }
public virtual DateTime ExpiryDate { get; private set; }
// external IAggregateRoot objects are linked by reference
public virtual int? UserId { get; private set; }
public virtual int? OrganizationId { get; private set; }
public virtual int? OrderId { get; private set; }
public void AttachToOrder(int orderId)
{
if (ExpiryDate >= DateTime.UtcNow)
throw new InvalidOperationException("Credit is expired.");
if (OrderId != null)
throw new InvalidOperationException("Credit is unavailable.");
OrderId = orderId;
}
public void DetachFromOrder()
{
if (OrderId == null)
throw new InvalidOperationException("Credit is available.");
OrderId = null;
}
}
}
假設我要在外鍵約束下保持該模型。 實體框架Fluent API需要導航屬性才能執行此操作。 因此,我無法直接持久化域模型,也無法從關系數據庫中的外鍵約束檢查中受益。
我的想法是繼承PM以添加所需的導航屬性。 由於EF也需要無參數的構造函數,因此很遺憾,我將不得不將其添加到DM中,盡管幸運的是,它不會對其不變量產生影響。
namespace Foo.Domain
{
// Adjusted Domain Model
public class Credit : IDomainEntity, IAggregateRoot
{
protected Credit() { }
public Credit(int? userId, int? organizationId, DateTime expiryDate)
: this()
// remainder of the class unchanged
}
}
namespace Foo.Infrastructure
{
// Persistence Model
public class Credit : Foo.Domain.Credit
{
protected Credit()
: base()
{
}
public Credit(int? userId, int? organizationId, DateTime expiryDate)
: base(userId, organizationId, expiryDate)
{
}
public virtual User User { get; private set; }
public virtual Organization Organization { get; private set; }
public virtual Order Order { get; private set; }
}
}
現在,我假設可以在Fluent API中像這樣使用它:
modelBuilder.Entity<Credit>()
.HasOptional<Order>(c => c.Order) // this is why I need the navigation property
.WithMany()
.HasForeignKey(c => c.OrderId);
..並像這樣定義我的DbContext:
namespace Foo.Infrastructure
{
public interface IFooDbContext
{
IDbSet<Credit> Credits { get; }
Task<int> SaveChangesAsync();
}
}
您對這種方法有何看法?
對我而言,主要缺點是從域實體轉換為持久性實體。 當從存儲庫獲取數據時-可以,只需將Foo.Infrastructure.Credit
為Foo.Domain.Credit
即可(沒有繼承)。 但是,當您需要保存新的Foo.Domain.Credit
,必須創建新的對象Foo.Infrastructure.Credit
並將屬性從第一到第二進行映射。 因此,您不能只調用new Foo.Domain.Credit
,您需要使用一個工廠,而該工廠必須了解Foo.Infrastructure.Credit
,這看起來並不好。 不幸的是,實體框架不允許我們將域實體設計為“純”的,而持久性卻是無知的,因此我們必須對其進行處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.