[英]How do I deal with database generated id values in a unit of work
請注意,我使用SQL Server 2008 R2作為持久性框架。 我沒有更改此選項。 我正在使用Micro-ORM進行持久化。 我也沒有選擇更改此選項。 第三,我沒有選擇將表標識列更改為向導。 它們必須保留為整數。
我要創建的聚合是一個有一些任務的項目。 我想將其保存到兩個表,一個表與父項目,另一個與任務,由父項目ID鏈接。 很簡單。 顯然,表結構是一個持久性細節,我想將其保留在域模型之外。 堅持這一點后,我想將項目的ID發送回用戶,以便他們可以導航到新創建的項目。
public class CreateNewProjectRequest
{
public int InterestingInteger { get; set; }
public string MoreDataNeededForRequest { get; set; }
}
public CreateProjectApplicationService
{
private readonly IUnitOfWork uow;
public CreateProjectApplicationService(IUnitOfWork uow)
{
this.uow = uow;
}
public int CreateNewProject(CreateNewProjectRequest request)
{
var project = ProjectAggregate.CreateFrom(request);
var projectRepository = new ProjectRepository(uow);
projectRepository.Add(project);
projectRepository.Save(project);
//db transaction commits
uow.Commit();
}
}
引用有關該主題的一些資源(沃恩·弗農(Vaughn Vernon)的DDD書和最新的Wrox DDD書《域驅動設計的模式,原理和實踐》,我發現存儲庫負責聚合根的持久性。 存儲庫接口位於域模型中。
在Wrox DDD書中,存在UnitOfWork
和IUnitOfWorkRepository
,它們的定義如下:
public interface IUnitOfWork
{
void RegisterAmended(IAggregateDataModel entity, IUnitOfWorkRepository unitofWorkRepository);
void RegisterNew(IAggregateDataModel entity, IUnitOfWorkRepository unitofWorkRepository);
void Commit();
void Clear();
}
public interface IUnitOfWorkRepository
{
void PersistCreationOf(IAggregateDataModel entity);
void PersistUpdateOf(IAggregateDataModel entity);
void PersistDeleteOf(IAggregateDataModel entity);
}
public class ProjectRepository : IProjectRepository, IUnitOfWorkRepository
{
//Simplified for example's sake, I didn't implement all of IUnitOfWorkRepository
private readonly IUnitOfWork uow;
public ProjectRepository(IUnitOfWork uow)
{
this.uow = uow;
}
public void Add(Project project)
{
unitOfWork.RegisterNew(project, this);
}
public void PersistCreationOf(IAggregateDataModel entity)
{
//Persist changes via micro ORM -- new id is available
}
}
提交的實現創建了一個事務並將其持久化。
我遇到的問題是,當調用Commit()
方法將事務持久化到數據存儲區時,我有一個在該過程中創建的新ID。 我知道CreateProjectApplicationService
可能涉及多個聚合(在我看來,它還沒有...),因此工作單元實現在此處管理事務,因此數據存儲處於一致狀態。
我不能只是從數據庫中播種ID。 我想使用scope_identity()
獲取數據庫生成的ID,因為它是一個自動遞增的列。
獲得此新插入的ID的最干凈的方法是什么? 或者,這里的工作單元是不適當的抽象,應該留給其他用例嗎?
在DDD中,工作單元是業務流程本身。 您所擁有的是一種流行的反模式。 無論如何,考慮到您的約束,最干凈的事情是使Id屬性可分配並在存儲庫中進行設置。
因此,您的項目將在repository.Add
方法中獲取ID。 關於添加任務,這應該是一項不同的操作,您正在嘗試在一個操作中做太多事情。 基本上,您使用的是“舊的”事務處理腳本(CRUD)方法,但帶有DDD術語。
通常,您應該對添加項目執行一個操作-> ProjectCreated [event]-> AddDefaultTasks。
用戶界面還應該更多地基於任務,而不是一次執行兩種不同的操作。
我想說,當數據庫負責生成ID時,您實際上不能做適當的DDD。 關鍵是,DDD並不是用魔術方法修補糟糕的代碼庫,而是要自上而下地進行適當的設計。 但是您現在負責打補丁,因此您實際上無法執行DDD。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.