Entity framework efcore2dbcontext的抽象
我正试图在我的数据库上下文层(EntityFramework 2.0)上进行抽象。Entity framework efcore2dbcontext的抽象,entity-framework,.net-core,entity-framework-core,asp.net-core-2.0,Entity Framework,.net Core,Entity Framework Core,Asp.net Core 2.0,我正试图在我的数据库上下文层(EntityFramework 2.0)上进行抽象。 Car.DataContext ------------------- public abstract class BaseCarContext : DbContext { protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Enti
Car.DataContext
-------------------
public abstract class BaseCarContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>(e =>
{
e.ToTable("Car");
});
modelBuilder.Entity<Car>(e => { e.ToTable("Cars"); });
}
}
public class CarContext : BaseCarContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured)
return;
optionsBuilder.UseSqlServer(@"Server = xxxx; Database = xxxx; Trusted_Connection = True;");
}
public DbSet<Car> Cars { get; set; }
}
Car.Logic
----------------
public interface ICarService
{
GetCarResponse RetrieveCar(int id);
void Save(int id);
...
}
public class CarService : ICarService
{
private readonly ICarService service;
// dbContext interface
public CarService(ICarService service){
this.service = service;
// injecting db context interface
}
public void Save(int id){
... saving using injected db context
// injected db context.Insert(new Car{ Name = "Honda" });
}
...
}
Car.DataContext
-------------------
公共抽象类BaseCarContext:DbContext
{
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
实体(e=>
{
e、 可折叠(“汽车”);
});
实体(e=>{e.ToTable(“Cars”);});
}
}
公共类CarContext:BaseCarContext
{
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
如果(optionsBuilder.IsConfigured)
返回;
optionsBuilder.UseSqlServer(@“服务器=xxxx;数据库=xxxx;可信连接=True;”);
}
公共数据库集车辆{get;set;}
}
汽车。逻辑
----------------
公共接口ICarService
{
GetCarResponse检索卡(int id);
无效保存(int-id);
...
}
公共类CarService:ICarService
{
专用只读ICarService服务;
//dbContext接口
公共汽车服务(ICarService服务){
服务=服务;
//注入数据库上下文接口
}
公共无效保存(int-id){
…使用注入的db上下文保存
//Insert(新车{Name=“Honda”});
}
...
}
如何提取ef core 2CarContext
以使用dbContext
save
我试图制作一个接口IDbContext
,该接口由CarContext
但这样我就不能使用dbContext.Cars.Insert
,因为我没有实现dbContext-Cars集合,所以我无法访问ef核心方法和属性
我当然可以使用具体的实现,但我正在尝试做一个抽象,这样我就可以使用单元测试
您将如何做到这一点?首先,您不需要对单元测试进行抽象。EF核心是100%测试友好型。其次,在我看来,对于EF(或任何ORM)来说,唯一真正可以接受的抽象是微服务或CQRS/事件源模式。它们实际上增加了价值,因为它们要么完全抽象依赖关系,要么解决实际的业务线问题。然而,这些模式也需要大量的努力才能正确实现,因此,它们通常是为大型、复杂的应用程序保留的
无论长短,只要直接使用EF,除非你有真正好的理由不这样做。测试不是一个很好的理由。首先,单元测试不需要抽象。EF核心是100%测试友好型。其次,在我看来,对于EF(或任何ORM)来说,唯一真正可以接受的抽象是微服务或CQRS/事件源模式。它们实际上增加了价值,因为它们要么完全抽象依赖关系,要么解决实际的业务线问题。然而,这些模式也需要大量的努力才能正确实现,因此,它们通常是为大型、复杂的应用程序保留的
无论长短,只要直接使用EF,除非你有真正好的理由不这样做。测试不是一个很好的理由。“EF Core是100%测试友好型的。”我不能同意这一点。我不能嘲笑SaveChange返回的内容。此外,如果使用ExecuteSqlCommand,测试将崩溃,因为UseInMemoryDatabase不支持它:“只有当上下文使用关系数据库提供程序时,才能使用特定于关系的方法”。
SaveChanges
返回受影响的记录计数。你怎么不能模拟返回一个int?其次,使用内存中的数据库不会是模仿。如果您实际上模拟了上下文,则可以存根ExecuteSqlCommand
执行任何您想要的操作。你不了解如何正确测试并不是EF-Core的缺陷。“EF-Core是100%测试友好型的。”我不能同意这一点。我不能嘲笑SaveChange返回的内容。此外,如果使用ExecuteSqlCommand,测试将崩溃,因为UseInMemoryDatabase不支持它:“只有当上下文使用关系数据库提供程序时,才能使用特定于关系的方法”。SaveChanges
返回受影响的记录计数。你怎么不能模拟返回一个int?其次,使用内存中的数据库不会是模仿。如果您实际上模拟了上下文,则可以存根ExecuteSqlCommand
执行任何您想要的操作。您不了解如何正确测试并不是EF Core的缺陷。