从数据库插入ID的问题

xpo*_*oci 3 c# entity-framework .net-core asp.net-core ef-core-2.2

我试图通过Entity Framework从数据库中获取最后插入的ID,但是我的问题在某种程度上是唯一的,我无法找到任何解决方案,而是重写了我的整个基础结构和业务层,所以我的所有ID都是Guid,能够手动创建,或在提交后通过另一个数据库调用获取最新记录。

这是问题所在。我有一个三层体系结构,在其中使用UoW,存储库,服务和外观。我将自上而下显示代码,以便您理解。

这是我的门面,在哪里uow.Commit呼唤SaveChanges()

public async Task<int> RegisterUserAsync(UserCreateDto user)
{
        using (var uow = UnitOfWorkProvider.Create())
        {
            var id = _userService.Create(user);
            await uow.Commit();
            return id;
        }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我仅将DTO发送到服务中,我的处理方式是这样的,我也在服务内部进行映射

public virtual int Create(TCreateDto entityDto)
{
        var entity = Mapper.Map<TEntity>(entityDto);
        Repository.Create(entity);
        return entity.Id;
}
Run Code Online (Sandbox Code Playgroud)

最后我的仓库看起来像这样

public TKey Create(TEntity entity)
{
        Context.Set<TEntity>().Add(entity);
        return entity.Id;
}
Run Code Online (Sandbox Code Playgroud)

有一些优雅的解决方案吗?就像我说的那样,我唯一的想法是在提交后将所有Id切换到Guid或第二个Id调用,这并不是很好的解决方案,因为当我想在一个事务中连接两个或多个表时,这是不可能的。

Iva*_*oev 5

EF Core解决该问题的方法很简单- 调用后即可使用实体实例的自动生成的PK SaveChanges[Async]。例如

var entity = Mapper.Map<TEntity>(entityDto);
Context.Add(entity);
// Here entity.Id contains auto-generated temporary value
// Other stuff...
Context.SaveChanges();
// Here entity.Id contains actual auto-generated value from the db
Run Code Online (Sandbox Code Playgroud)

因此,问题更多是在基础架构的设计中-所有这些(不必要的)UoW,存储库,服务和外观都只是隐藏了该功能。

我在您的体系结构中看到的唯一相对简单而优雅的解决方案是将服务返回类型从更改intFunc<int>,例如

public virtual Func<int> Create(TCreateDto entityDto)
{
    var entity = Mapper.Map<TEntity>(entityDto);
    Repository.Create(entity);
    return () => entity.Id; // <--
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在立面中使用

public async Task<int> RegisterUserAsync(UserCreateDto user)
{
    using (var uow = UnitOfWorkProvider.Create())
    {
        var id = _userService.Create(user);
        await uow.Commit();
        return id(); // <-- the actual id!
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

实际上,EF Core提供了另一个选项,该选项使您可以保持当前设计的完整性-HiLo密钥生成策略,但前提数据库提供者支持它。我可以肯定地说Microsoft.EntityFrameworkCore.SqlServerNpgsql.EntityFrameworkCore.PostgreSQL确实分别ForSqlServerUseSequenceHiLoForNpgsqlUseSequenceHiLo流畅的API 支持它。