【问题标题】:How can I access the Database field of a database context interface?如何访问数据库上下文接口的数据库字段?
【发布时间】:2020-04-22 17:29:55
【问题描述】:

我正在使用 .NET Core 3.1。我有以下问题:我想在应用层做一个事务。我有一个 DbContext 接口,因为我不想访问拥有 DbContext 类的基础设施层。在其他架构中,我能够访问 Database 字段,因此也能够访问 Transaction,因为我正在注入 DbContext 类。现在我正在注入我创建的 DbContext 接口,但我不知道如何添加必要的字段,从而可能使用 DbContext 类中的数据库字段。 这是基础设施层 DbContext。

   public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long>, IApplicationDbContext
   {
        private readonly ICurrentUserService _currentUserService;
        private readonly IDateTime _dateTime;
        public ApplicationDbContext(DbContextOptions options, ICurrentUserService currentUserService, IDateTime dateTime)
            : base(options)
        {
            _currentUserService = currentUserService;
            _dateTime = dateTime;
        }
        public DbSet<City> Cities { get; set; }
   }

这里是Application层的DbContext接口。

    public interface IApplicationDbContext
    {
       Task<int> SaveChangesAsync(CancellationToken cancellationToken);
       public DbSet<City> Cities { get; set; }
    }

我希望能够做这样的事情

   public class CityService
   {
      private readonly IApplicationDbContext _context;
      public CityService(IApplicationDbContext context)
      {
         _context = context;
      }
   public Task AddAsync(City city, CancellationToken cancellationToken)
   {
      using var transaction = _context.Database.BeginTransaction();
      try
      {
         await _context.AddAsync(city, cancellationToken);
         await _context.SaveChangesAsync(cancellationToken);
         await transaction.CommitAsync();
      }
      catch (Exception e)
      {
         await transaction.RollbackAsync();
      }
   }
   }

【问题讨论】:

  • 关于主题已经有多个问题:如何使用事务与 EF... 有答案 .. 搜索:工作单元
  • 在旁注中,您可能应该使用DbSet.Add 而不是AddAsync。另请参阅文档说明:"This method is async only to allow special value generators, such as the one used by 'Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo', to access the database asynchronously. For all other cases the non async method should be used."

标签: c# .net entity-framework .net-core onion-architecture


【解决方案1】:

...如何在使用 DbContext 接口时使用事务。

如果要使用接口,则创建并实现适当的方法并调用。

public interface IApplicationDbContext
{
   Task<int> SaveChangesAsync(CancellationToken cancellationToken);
   DbSet<City> Cities { get; set; }

   // added
   IDbContextTransaction BeginTransaction();
}

public class ApplicationDbContext : ... IApplicationDbContext
{
    // added
    public IDbContextTransaction BeginTransaction()
    {
        return _context.Database.BeginTransaction();
    }
}

【讨论】:

  • 你的回答让我对我的问题有了一个想法。这也是一个很好的解决方案,但我不想让它更抽象。另外,如果你想看看我是如何做到的,我在这里添加了我的答案。
【解决方案2】:

我找到了解决问题的方法。在界面中我添加了以下字段:

public DatabaseFacade Database { get; }

之后,我以我在问题的最后一个代码部分中想要的方式使用它。一切都像魅力一样!我不知道这是否是最好的方法,但它对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    相关资源
    最近更新 更多