繁体   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