C# ASP.NET核心中现有存储库模式中工作单元的正确实现
你好 我正在使用存储库模式。但有人建议我使用包含工作单元。我读了很多文章,老实说,我发现一个文档太复杂了,难以理解 假设我有一个非泛型存储库C# ASP.NET核心中现有存储库模式中工作单元的正确实现,c#,asp.net,interface,repository-pattern,unit-of-work,C#,Asp.net,Interface,Repository Pattern,Unit Of Work,你好 我正在使用存储库模式。但有人建议我使用包含工作单元。我读了很多文章,老实说,我发现一个文档太复杂了,难以理解 假设我有一个非泛型存储库 // My Interface public interface IProductRepository{ IQueryable Products(); IQueryable ProductById(int id); void InsertProduct(Product product); void UpdateProduc
// My Interface
public interface IProductRepository{
IQueryable Products();
IQueryable ProductById(int id);
void InsertProduct(Product product);
void UpdateProduct(Product product);
void DeleteProductById(int id);
}
// Abstract Implementation
public class ProductRepository : IProductRepository{
private readonly MyDbContext context;
public ProductRepository(MyDbContext context){
this.context= context;
}
public IQueryable Products(){
context.Product();
}
public IQueryable ProductById(int id){
context.Product().Where(prod=>prod.Id == id);
}
public void InsertProduct(Product product){
context.Product.Add(product);
context.SaveChanges();
}
public void UpdateProduct(Product product){
context.Product.Update(product);
context.SaveChanges();
}
public void DeleteProductById(int id){
var product = ProductById(id);
context.Product.Remove(product);
context.SaveChanges();
}
}
我的问题是,我如何在这里使用工作单位?你能给我看下面的代码吗。理解这一点对我非常有帮助。项目中需要工作单元的主要原因是需要确保所有存储库都具有相同的上下文。工作单元和存储库之间的关系,就像实体框架中DbContext和DbSet之间的关系一样
如果您想实现您的UnitOfWork,您可以参考以下链接:在IPProductRepository中添加保存方法
// My Interface
public interface IProductRepository{
// ...
void Save();
}
然后在具体的ProductRepository中,您要做两件事:
如果您了解EFCore是如何做到这一点的,那么您实际上定义了一个上下文,并定义了您想要在该上下文中使用的类。从中,他们定义了一个从DbContext继承的BloggingContext。以下示例来自microsoft:
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=localdb)\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;");
}
}
公共类BloggingContext:DbContext
{
公共数据库集博客{get;set;}
公共DbSet Posts{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
optionsBuilder.UseSqlServer(@“Server=localdb)\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;”);
}
}
在本例中,它们有一个Blog类和一个Post类,在数据库()上运行迁移和更新时,会将它们创建到表中。既然您已经在BloggingContext中定义了Blog和Post,那么您就可以创建BloggingContext的实例(很好地使用依赖注入,如果您愿意,您可以在这里阅读更多关于它的内容)并使用linq to your hearts内容,而无需定制存储库或工作单元。一旦您定义了在什么上下文中需要什么类,EF就会完成这项工作。
话虽如此,我们确实在我工作的地方使用了存储库和工作单元,如果有理由使用这些模式的话,那就太好了,但如果你不这样做,或者你自己去学习,EF确实做得很好。你的基础ORM(实体框架)已经遵循了存储库和工作单元模式。因此,仅仅是放弃你的禁欲而不是另一个(相同的)禁欲就能达到目的。但是如果你坚持的话,就复制它的功能。从
UpdateProduct
、DeleteProduct
等中删除所有context.SaveChanges
,并添加单独的SaveChanges
方法(当然,这只会做cotnext.SaveChanges
)。你的意思是,使用EF时我不需要学习工作单元?这就是你的意思吗?因为EF有自己的存储库和工作单元模式?如果你不知道什么是工作单元,那么你肯定需要了解它是什么,否则你将如何实现它。然后您将看到EF DbContext已经遵循了工作单元模式。很好的交叉引用:@Evk,如果EF有,那么我不需要实现工作单元模式,对吗?
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=localdb)\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;");
}
}