当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Using DI but getting : An entity object cannot be referenced by multiple instances of IEntityChangeTracker but

问题描述:

None of the questions I have reviewed on this subject are using IOC whereas I am so I don't understand why I am getting this error. As I understand it, if I only have one instance of my context, I shouldn't be receiving this error. This is a broken down version of my setup.

I am trying to run this:

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();

My _productService:

public class ProductService : IProductService

{

private readonly IRepository<Product> _productRepository;

public ProductService(IRepository<Product> productRepository)

{

_productRepository = productRepository;

}

//Code removed for brevity

}

_categoryService is pretty much the same as _productService.

IRepository is like this:

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);

}

}

I am registering my context per request like so:

builder.RegisterType<CcDataContext>().As<IDbContext>().InstancePerRequest();

Bearing this in mind, the way I see it, _productService and _categoryService should have the same instance of the context so I am confused as to why I get the error.

Edit

This is my context:

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>();

}

}

网友答案:

This doesn't have anything to do with your DI container. That error means that somewhere in your context, you have created two DbSet properties that both point to the same entity.

Since the advent of ASP.NET Identity, the most common cause of this is individuals trying to add their own DbSet<ApplicationUser> property, when IdentityDbContext<ApplicationUser> already has one, which your application's context inherits.

Not sure if that's your problem, because you haven't specified what version of MVC you're using or posted the contents of your context. That should give you enough to look into the issue, though.

网友答案:

I've found the reason for this. It was down the the caching I am performing on the _categoryService. My Get() method looks like this:

public IEnumerable<Category> Get()
{
    return _cacheManager.Get(CcCacheCategoryAll, () => (_categoryRepository.Table.AsEnumerable()));
}

Basically, because I am not detaching my entities from the context they were in when they were cached, I then get the cached versions in a later request and they don't have the same context. So although it's not the DI at fault, it is because the context doesn't match between the entities.

分享给朋友:
您可能感兴趣的文章:
随机阅读: