c# - DDD : Entity identity before being persisted

标签 c# domain-driven-design repository-pattern domain-model aggregateroot

在领域驱动设计中,实体的定义特征之一是它具有身份。

问题:

我无法在创建实例时为实体提供唯一标识。一旦实体持久化(该值由底层数据库提供),此身份仅由存储库提供。

此时我无法开始使用 Guid 值。现有数据使用 int 主键值存储,我无法在实例化时生成唯一的 int。

我的解决方案:

  • 每个实体都有一个标识值
  • 身份仅在持久化后设置为真实身份(由数据库提供)
  • 在持久化之前实例化时将身份设置为默认值
  • 如果身份是默认的,则实体可以通过引用进行比较
  • 如果标识不是默认的,则实体可以通过标识值进行比较

代码(所有实体的抽象基类):

public abstract class Entity<IdType>
{
    private readonly IdType uniqueId;

    public IdType Id
    {
        get 
        { 
            return uniqueId; 
        }
    }

    public Entity()
    {
        uniqueId = default(IdType);
    }

    public Entity(IdType id)
    {
        if (object.Equals(id, default(IdType)))
        {
            throw new ArgumentException("The Id of a Domain Model cannot be the default value");
        }

        uniqueId = id;
    }

    public override bool Equals(object obj)
    {
        if (uniqueId.Equals(default(IdType)))
        { 
            var entity = obj as Entity<IdType>;

            if (entity != null)
            {
                return uniqueId.Equals(entity.Id);
            }
        }

        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return uniqueId.GetHashCode();
    }
}

问题:

  • 您认为这是在创建实例时生成 Guid 值的一个很好的替代方法吗?
  • 是否有更好的解决方案来解决这个问题?

最佳答案

在实例化实体对象时,您可以使用序列生成器生成唯一的 int/long 标识符。

界面如下:

interface SequenceGenerator {
    long getNextSequence();
}

序列生成器的典型实现使用数据库中的序列表。序列表包含两列:sequenceNameallocatedSequence

当第一次调用 getNextSequence 时,它会向 allocatedSequence 列写入一个大值(例如 100)并返回 1 。下一次调用将返回 2 而无需访问数据库。当 100 序列用完时,它会再次读取 allocatedSequence 并将其递增 100

查看 Hibernate 源代码中的 SequenceHiLoGenerator。它基本上执行我上面描述的操作。

关于c# - DDD : Entity identity before being persisted,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21250666/

相关文章:

c# - 单击按钮时wpf命令未执行的问题

c# - LLBLGen - 如何使用 CatalogNameOverwriteHashtable

java - 存储库模式 : Can a repository use other repositories?

c# - 处理返回 HttpWebResponse 的方法中的错误

c# - 使用最小起订量模拟 IEnumerable<T>

domain-driven-design - 在 DDD 架构中将表映射到域类

c# - NHibernate IQueryable 集合作为根的属性

.net - N 层开发中的 DDD 概念

c# - Entity Framework ,存储库模式

c# - 存储库应该公开实体对象吗?