微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

实体框架核心中的实施工作单元

如何解决实体框架核心中的实施工作单元

我已经在Entity Framework Core中以另一种方式实现了工作单元。

上下文:

public class DaleContext : DbContext,IDaleContext
{
    private readonly IConnectionStringProvider _connectionStringProvider;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UsesqlServer(_connectionStringProvider.ConnectionString);
        base.OnConfiguring(optionsBuilder);
    }

    public DaleContext(IConnectionStringProvider connectionStringProvider)
    {
        _connectionStringProvider = connectionStringProvider;
    }
    
    public DbSet<ProductProducts { get; set; }

    public override int SaveChanges()
    {
        ChangeTracker.DetectChanges();

        var modifiedEntries = ChangeTracker.Entries()
            .Where(x =x.State == EntityState.Added || x.State == EntityState.Modified).ToList();

        return base.SaveChanges();
    }
}

工作单元:

public class UnitOfWork : IUnitOfWork
{
    public UnitOfWork(DbContext dbContext)
    {
        DbContext = dbContext;
    }

    public DbContext DbContext { get; set; }

    public int Commit()
    {
        return DbContext.SaveChanges();
    }

    public async Task<intCommitAsync()
    {
        return await DbContext.SaveChangesAsync();
    }
}

存储库:

public class Repository<TEntity: Idisposable,IRepository<TEntity>
where TEntity : class
{
    private readonly UnitOfWork _unitOfWork;

    public Repository(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork as UnitOfWork;
    }

    public void dispose()
    {
        _unitOfWork.DbContext.dispose();
    } 

    public void Create(TEntity entity)
    {
        _unitOfWork.DbContext.Entry(entity).State = EntityState.Added;
    }
}

我已经全部注入了autofac:

public static class Container
{
    public static ContainerBuilder RegisterInfraestructure(this ContainerBuilder containerBuilder)
    {
        containerBuilder.RegisterType<UnitOfWork>().As<IUnitOfWork>();

        return containerBuilder;
    }
}

public static class Container
{
    public static ContainerBuilder RegisterDataResources(this ContainerBuilder containerBuilder)
    {
        var configurationBuilder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json");

        var configuration = configurationBuilder.Build();

        containerBuilder.Register(x =new ConnectionStringProvider(configuration.GetConnectionString("Fgcm.Dale"))
        ).As<IConnectionStringProvider>();

        containerBuilder.RegisterType<DaleContext>().As<DbContext>().As<IDaleContext>();

        return containerBuilder;
    }
} 

public static class Container
{
    public static ContainerBuilder RegisterRepository(this ContainerBuilder containerBuilder)
    {
        containerBuilder.RegisterType<CustomerRepository>().As<ICustomerRepository>();
        containerBuilder.RegisterType<ProductRepository>().As<IProductRepository>();
        containerBuilder.RegisterType<SaleDetailRepository>().As<ISaleDetailRepository>();
        containerBuilder.RegisterType<SaleRepository>().As<ISaleRepository>();
        
        containerBuilder.RegisterDataResources();
        containerBuilder.RegisterInfraestructure();

        return containerBuilder;
    }
}

public static class Container
{
    public static ContainerBuilder RegisterapplicationserviceResources(this ContainerBuilder
    containerBuilder)
    {
        containerBuilder.RegisterRepository();

        containerBuilder.RegisterType<Daleapplicationservice>().As<IDaleapplicationservice>();

        return containerBuilder;
    }
}

当我尝试保存数据时不起作用(不插入数据)...我想知道为什么?这是我尝试保存的时间:

    public Product Create(Product product)
    {
        try
        {
            _productRepository.Create(product);
            _unitOfWork.Commit();
            return product;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
            return null;
        }
    }

当然,所有注入都是:

    private readonly ICustomerRepository _customerRepository;
    private readonly IProductRepository _productRepository;
    private readonly ISaleDetailRepository _saleDetailRepository;
    private readonly ISaleRepository _saleRepository;
    private readonly IUnitOfWork _unitOfWork;

    public Daleapplicationservice(IProductRepository productRepository,ICustomerRepository customerRepository,ISaleRepository saleRepository,ISaleDetailRepository saleDetailRepository,IUnitOfWork unitOfWork)
    {
        _productRepository = productRepository;
        _customerRepository = customerRepository;
        _saleRepository = saleRepository;
        _saleDetailRepository = saleDetailRepository;
        _unitOfWork = unitOfWork;
    }

我想念什么?

PS:所有这些均适用于.NET Core Web Api。

解决方法

@ zolty13提示您DbContextDaleContext)的Instance scope可能不正确。默认情况下,Autofac将实例范围设置为Instance per dependency(也称为“瞬态”生存期),这意味着将为依赖它的每个类创建DaleContext的新实例。因此,您的UnitOfWorkDaleContext接收的IProductRepository实例不同。因此IProductRepository中的更改不会反映在UnitOfWork中。

解决此问题的一种方法是避免像@Igor建议那样对DbContext进行复杂的包装。您真的需要这个UnitOfWork吗?相反,请使用具有一个实例DaleContext的存储库类,并在其中进行所有数据库更改并保存。

或者(如果您确实认为自己需要UnitOfWork),则可以在instance per request范围内注册DaleContext。请注意:实体框架的DbContext是不是线程安全的,因此,如果您需要进行并发工作,则这不是一种安全的方法。

否则,请继续阅读Instance scope

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。