EF DbContext and Ninject

本文关键字:Ninject and DbContext EF | 更新日期: 2023-09-27 17:59:04

前一段时间我问了一个问题,为什么当我联合两个实体集合时,默认的相等比较器似乎不起作用。

EF码优先-Linq到实体联合均衡器

答案是因为我使用了DbContext的两个不同实例,因此引用不同。

所以现在我正试图在请求中共享我的DbContent。我看到了一些"复杂"的例子,但我想我应该尝试一个更简单的解决方案。

所以我创建了一个IDbContext接口,它简单地概述了我的实体

public interface IDbContext {
   int SaveChanges();
   DbSet<News> News { get; set; }
   DbSet<Category> Categories { get; set; }
}

然后我的DbContext实现如下:

public class SiteContext : DbContext, IDbContext {
   public DbSet<News> News { get; set; }
   public DbSet<Category> Categories { get; set; }
   protected override void OnModelCreating(DbModelBuilder modelBuilder) {
      ...
   }
}

然后在我的两个存储库(NewsRepository和CategoryRespository)中,我将IDbContext作为构造函数参数

IDbContext _db;
public NewsRepository(IDbContext db) {
    _db = db;
}

所以现在我假设,如果我在请求范围中将IDbContext绑定到SiteContext,我的存储库将共享相同的上下文?

 kernel.Bind<IDbContext>().To<SiteContext>().InRequestScope();

然而,当我再次尝试上一个问题中的联盟时,我仍然收到重复的实体!我做错了什么?如何判断我是否在一个请求中使用了相同的上下文?

EF DbContext and Ninject

因为当构建每个存储库时,Ninject将为每个存储库提供一个新的SiteContext实例。这就是为什么它不起作用。使用工作单元实现是个好主意,这意味着所有存储库都使用相同的上下文
UnitOfWork将接受一个关于建筑的IDbContext。

像这样的东西会工作

private IDbContext _context;
public UnitOfWork(IDbContext context)
{
    _context = context
}
private _INewsRepository;
public INewsRepoitory 
{
    get{
         if(_INewsRepository == null)
         {
              _INewsRepository = new NewsREpository(_context);
              return _INewsRepository;
         }
         else
         {
              return _INewsRepository;
         }    
}

为了改进feanz的解决方案,我仍然会用Ninject:对INewsReserve进行属性注入

[Inject]
public INewsRepository NewsRepo {get;set;}

每次创建IUnitOfWork时,都会创建一个INewsReserve。这仍然必须添加到您的ninject绑定中。