C# 在实体框架核心中实现工作单元
我已经在实体框架核心中以下一种方式实现了工作单元 背景:C# 在实体框架核心中实现工作单元,c#,entity-framework-core,asp.net-core-webapi,autofac,C#,Entity Framework Core,Asp.net Core Webapi,Autofac,我已经在实体框架核心中以下一种方式实现了工作单元 背景: public class DaleContext : DbContext, IDaleContext { private readonly IConnectionStringProvider _connectionStringProvider; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
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();
}
}
当然,所有这些都是注入的:
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;
}
我错过了什么
注:所有这些都适用于.NET核心Web Api。正如@zolty13所暗示的那样,
DbContext
(DaleContext
)可能不正确。默认情况下,Autofac将实例范围设置为(也称为“瞬态”生存期),这意味着将为依赖它的每个类创建DaleContext
的新实例。因此,您的UnitOfWork
接收的DaleContext
实例与IProductRepository
不同。因此,IProductRepository
中的更改不会反映在UnitOfWork
中
解决这个问题的一种方法是避免像@Igor suggest这样复杂地包装DbContext。你真的需要这个工作单元吗?相反,使用一个具有DaleContext
实例的存储库类,并在其中进行所有DB更改并保存它们
或者(如果你真的认为你需要一个工作单元
),你可以用一个作用域注册你的DaleContext
。注意:实体框架的DbContext不是线程安全的,所以如果您需要并发工作,这不是一种安全的方法
否则,请继续阅读。您确定di作用域是好的吗?请尝试只发布相关代码。太多的代码只会模糊你的问题。此外,写“当我试图保存数据时,它不起作用”并不能真正解释你的感受。你犯了什么错误?到底哪里出了问题?如果你能指出代码中的某一行,那就更好了。@zolty13我认为是的。。。但是如何跟踪呢?@Xerilio更新了
“我已经在entity framework core中以下一种方式实现了工作单元:“
← 为什么?类型DbContext
是UoW模式的实现,类型DbSet
是存储库模式的实现。为什么要在您自己的相同模式实现中重新包装这些类型?您没有添加任何有价值的东西,只是添加了更多的代码和糟糕的抽象,这导致代码更难阅读、调试和使用。
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;
}
}
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;
}