c#在客户端应用程序中管理领域实体的渐进式标识

本文关键字:实体 渐进式 标识 管理 客户端 应用程序 | 更新日期: 2023-09-27 18:07:30

我有这个问题建模我的一个实体:

  1. 我的实体必须有一个用户用来识别单个对象的强制ID字段
  2. 用户不想手动输入ID,但它必须由应用程序生成,每次递增1
  3. 应用程序只存在于客户端机器上,在服务器上只有db

根据1。我创建Id字段是强制性的(而不是可空的),以这种方式必须提供创建实例,但程序如何知道必须使用哪个Id ?

理想情况下,我必须查询db以获得最大id,添加1并使用此值,但如何做到这一点?为了看到它似乎是我的领域对象的问题,我想将领域层与数据访问层隔离,所以我不能直接从实体调用存储库。

可能的解决方案:

  1. 我看联锁。增量,但如果任何用户都可以在其客户端上创建新实例,如何使用它?
  2. 将逻辑移动到应用逻辑层:在那里我可以调用存储库,获取ID,创建类并调用存储库保存类。以这种方式将域逻辑(增量id是特定的用户请求)移出域层
  3. 在域层中定义存储库接口,在实体的构造方法中调用该接口。所有这些都与依赖注入有关,但是怎么做呢?我在引导程序中使用ninject,所有引用都是从上到下的,我如何将其还原为域层,使其调用上级层,避免服务定位器反模式(否则可以简单地在我的函数中编写NinjectKernel.Get())
  4. 我发现了这篇文章,它很有趣,但他以一种不好的方式使用我的解决方案(没有接口),没有将字段定义为强制性的,所以他可以创建一个新的实例,而不指定id

有更好的解决方案吗?

编辑

一些代码来更好地解释这种情况:

Public MyClass {
 public int Id{get;set;}
 .....
 public MyClass(int id){
  if(id != null)
   this.Id = id;
  else
   throw (new ArgumentException)
  .....
 }
}

所以我不能做MyClass mc = new MyClass(null);但是我需要在

之前加上id

在数据访问层我使用NHibernate和Uow/Repository模式

在我可以得到一个有效的ID后,我可以写

UnitOfWork.MyClassRepository.Add(mc);

c#在客户端应用程序中管理领域实体的渐进式标识

还有另一种解决方案,用于一些高负载的分布式应用程序。这个想法是创建一个单独的服务(web服务)来获得一个新的ID。在内部,实现可以像这样简单:

public int GetNextId()
{
    return Interlocked.Increment(ref _lastId);
}

虽然你显然必须在服务启动时从数据库中获取最后一个id。

然后,在创建实体之前,您只需让每个客户端应用程序调用此服务。

但老实说,我会从数据库生成的Id开始,或者如果可能的话使用Guids。

更新:另一种选择。为每个客户端分配一个唯一的id (int)。然后在每次需要新Id时使用内部计数器,但将其与客户端混合为ClientId * 10000 + LastId。这类似于Hi/Lo生成器

在您的域模型中,您可以创建从DB获取id的存储库。并且您必须创建使用存储库生成id的域对象的工厂。