Моя модель домена использует EntityFramework 4.1 (а я использую код в первую очередь) для обновления моей БД с помощью связанных сущностей. У меня есть таблица членов, а затем таблица «многие ко многим». Проблема заключается в том, что когда я пытаюсь выполнить обновление для члена с измененными разрешениями, код выдает ошибку времени выполнения « На объект сущности нельзя ссылаться несколькими экземплярами IEntityChangeTracker », когда я устанавливаю следующие из моего репозитория класса:
_context.Entry (entity) .State = EntityState.Modified
Теперь я прочитал посты по следующим ссылкам, но они выглядят устаревшими, и часть кода не работает в EF 4.1 / MVC3:
Итак, мои вопросы:
- Что мне нужно сделать, чтобы этот код работал для EF 4.1 и MVC 3 (например, HttpContext.Current ["myDBEntities"] не может быть проиндексирован с использованием сегодняшнего фреймворка)
- Что еще более важно, где должен находиться этот код? Я не могу понять, где разместить метод или класс "datacontext per user per request", как описано в первой ссылке. Это не имеет смысла в моем доменном проекте, потому что у него нет доступа к HttpContext, поэтому, если он находится в моем веб-проекте, как мне передать его в домен?
Чтобы помочь вам, ниже приведена урезанная версия модели моего домена:
public class Entity
{
public int Id { get; set; }
}
public class Member : Entity
{
public string Name { get; set; }
public virtual List<MemberPosition> Positions { get; set; }
}
public class MemberPosition : Entity
{
public string Name { get; set; }
}
public class EfDbContext : DbContext
{
public DbSet<Member> Members { get; set; }
public DbSet<MemberPosition> MemberPositions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MemberMap());
modelBuilder.Configurations.Add(new MemberPositionMap());
}
}
public class MemberMap : EntityTypeConfiguration<Member>
{
public MemberMap()
{
ToTable("Members");
HasMany(m => m.Positions).WithMany().Map(
m => m.ToTable("Member_MemberPositions").MapLeftKey("MemberId").MapRightKey("PositionId"));
}
}
public class MemberPositionMap : EntityTypeConfiguration<MemberPosition>
{
public MemberPositionMap()
{
ToTable("MemberPositions");
Property(x => x.Name).IsRequired().HasMaxLength(100);
}
}
public interface IRepository<TEntity>
{
bool Update(TEntity entity);
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : Entity
{
private readonly EfDbContext _context;
private readonly DbSet<TEntity> _dbSet;
public Repository(EfDbContext context)
{
_context = context;
_dbSet = _context.Set<TEntity>();
}
public bool Update(TEntity entity)
{
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
return true;
}
}
И, наконец, урезанная версия метода Edit в моем MemberController:
public class MemberController : Controller
{
[HttpPost]
public ActionResult Edit(MemberDetailViewModel memberDetailViewModel)
{
if (ModelState.IsValid)
{
var updatedMember = // Gets the member data from the view model...
var memberRepository = // Creates a Repository<Member>;
memberRepository.Update(updatedMember);
return // blah... blah... blah...
}
}
}
Любые предложения приветствуются!
РЕДАКТИРОВАТЬ: ЭТО РЕШЕНИЕ (ЭТО ЛЕГКО!)
В контроллере App_Start.NinjectMVC3 используйте следующий код (убедитесь, что InRequestScope) присутствует. В моем исходном коде это не было, следовательно, оно не работало ...
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
}