我在这个问题上所审查的问题都没有使用IOC,而我却不明白为什么我会收到此错误。据我了解,如果我只有一个上下文实例,我不应该收到这个错误。这是我的设置的细分版本。
我正试图这样做:
var product = new Product();
product.ShortText = "something";
foreach (var category in _categoryService.Get().Take(5).ToList())
product.Categories.Add(category);
_productService.Update(product);
_productService.SaveChanges();
我的_productService
:
public class ProductService : IProductService
{
private readonly IRepository<Product> _productRepository;
public ProductService(IRepository<Product> productRepository)
{
_productRepository = productRepository;
}
//Code removed for brevity
}
_categoryService
与_productService
几乎相同。
IRepository
是这样的:
public class EfRepository<T> : IRepository<T> where T : BaseEntity
{
private readonly IDbContext _context;
private IDbSet<T> _entities;
public EfRepository(IDbContext context)
{
_context = context;
}
protected virtual IDbSet<T> Entities
{
get { return _entities ?? (_entities = _context.Set<T>()); }
}
public IQueryable<T> Table
{
get { return Entities; }
}
public void Update(T entity)
{
Entities.AddOrUpdate(m => m.Id, entity);
}
}
我按照请求注册我的上下文:
builder.RegisterType<CcDataContext>().As<IDbContext>().InstancePerRequest();
考虑到这一点,我看到它的方式,_productService
和_categoryService
应该有相同的上下文实例,所以我很困惑为什么我得到错误。
修改
这是我的背景:
public class CcDataContext : DbContext, IDbContext
{
static CcDataContext()
{
Database.SetInitializer<CcDataContext>(null);
}
public CcDataContext()
: base("CcDataContext") //String.Format("Name={0}", CcConfig.Get("ConnectionStringName")))
{
}
public DbSet<Website> Websites { get; set; }
public DbSet<Store> Stores { get; set; }
public DbSet<StoreView> StoreViews { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<CustomerAddress> CustomerAddresses { get; set; }
public DbSet<CustomerContact> CustomerContacts { get; set; }
public DbSet<CustomerRole> CustomerRoles { get; set; }
public DbSet<RolePermission> PermissionRoles { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
public IDbSet<T> Set<T>() where T : BaseEntity
{
return base.Set<T>();
}
}
答案 0 :(得分:0)
这与您的DI容器没有任何关系。该错误意味着在您的上下文中的某个位置,您创建了两个DbSet
属性,这两个属性都指向同一个实体。
自ASP.NET身份出现以来,最常见的原因是个人尝试添加自己的DbSet<ApplicationUser>
属性,当IdentityDbContext<ApplicationUser>
已经有一个属性时,应用程序的上下文继承。
不确定这是否是您的问题,因为您还没有指定您正在使用或发布上下文内容的MVC版本。但是,这应该足以让你研究这个问题。
答案 1 :(得分:0)
我找到了原因。这是我在_categoryService
上执行的缓存。我的Get()
方法如下所示:
public IEnumerable<Category> Get()
{
return _cacheManager.Get(CcCacheCategoryAll, () => (_categoryRepository.Table.AsEnumerable()));
}
基本上,因为我没有将我的实体从它们被缓存时所处的上下文中分离出来,然后我在稍后的请求中获得缓存版本,并且它们没有相同的上下文。因此,尽管DI不是故障,但这是因为实体之间的上下文不匹配。