簡體   English   中英

如何在工作單元中處理數據庫生成的ID值

[英]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書中,存在UnitOfWorkIUnitOfWorkRepository ,它們的定義如下:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM