Использование кода EF 4.1 Во-первых, у меня есть объект Member , и он, в свою очередь, имеет два отношения " один-ко-многим " для HomeAddress и WorkAddress .Он также имеет логическое свойство для указания, использовать ли один из этих адресов или нет.
У меня есть две проблемы, которые я не могу выяснить:
Каждый раз, когда я обновляю адрес участника, новая запись добавляется в таблицу MemberAddresses (с новымЗначение идентификатора) и существующая запись не удаляется.Хотя это выглядит хорошо с точки зрения внешнего интерфейса, так как HomeAddressId и WorkAddressId в родительской таблице Members обновляются с новой записью, старые записи хранятся в таблице (без изменений).Я не хочу добавлять новую адресную запись при обновлении адреса.Я только хочу обновить существующую запись.Если нужно добавить новый, я хотя бы хочу, чтобы он очистил старый.
Бывают моменты, когда я хочу удалить запись адреса из таблицы.Например, если член ранее имел связанный HomeAddress, а позже DontUseHomeAddress установлен в true, я хочу, чтобы адрес был удален из таблицы.До сих пор я пытался установить его на ноль, но это просто предотвращает любые обновления.Это не удаляет его.
Я уверен, что я пропускаю только часть кода, поэтому я включаю весь соответствующий код ниже, который, я думаю, может повлиять на это.
public abstract class Entity
{
public int Id { get; set; }
}
public class Member : Entity
{
public string Name { get; set; }
public bool DontUseHomeAddress { get; set; }
public virtual MemberAddress HomeAddress { get; set; }
public bool DontUseWorkAddress { get; set; }
public virtual MemberAddress WorkAddress { get; set; }
//... other properties here ...
}
public class MemberMap : EntityTypeConfiguration<Member>
{
public MemberMap()
{
ToTable("Members");
Property(m => m.Name).IsRequired().HasMaxLength(50);
//TODO: Somehow this is creating new records in the MemberAddress table instead of updating existing ones
HasOptional(m => m.HomeAddress).WithMany().Map(a => a.MapKey("HomeAddressId"));
HasOptional(m => m.WorkAddress).WithMany().Map(a => a.MapKey("WorkAddressId"));
}
}
public class MemberAddressMap : EntityTypeConfiguration<MemberAddress>
{
public MemberAddressMap()
{
ToTable("MemberAddresses");
Property(x => x.StreetAddress).IsRequired().HasMaxLength(255);
Property(x => x.City).IsRequired().HasMaxLength(50);
Property(x => x.State).IsRequired().HasMaxLength(2);
Property(x => x.ZipCode).IsRequired().HasMaxLength(5);
}
}
Вот метод InsertOrUpdate из моего класса репозитория, который вызывает мой контроллер:
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 InsertOrUpdate(TEntity entity)
{
if(entity.Id == 0)
{
_dbSet.Add(entity);
}
else
{
_context.Entry(entity).State = EntityState.Modified;
}
_context.SaveChanges();
return true;
}
//... Other repository methods here ...
}
EDIT: добавление кода для UnitOfWork и MemberServices
открытый класс MemberServices: IMemberServices {private readonly IUnitOfWork _unitOfWork;приватный только для чтения IRepository _memberRepository;
public MemberServices(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_memberRepository = unitOfWork.RepositoryFor<Member>();
}
public Member Find(int id)
{
return _memberRepository.FindById(id);
}
public bool InsertOrUpdate(Member member)
{
// if(member.HomeAddress != null)
// _unitOfWork.SetContextState(member.HomeAddress, EntityState.Modified);
//
// if(member.WorkAddress != null)
// _unitOfWork.SetContextState(member.WorkAddress, EntityState.Modified);
//
// if(member.DontUseHomeAddress)
// {
// //TODO: This is an attempted hack... fix it by moving somewhere (possibly to repository)
// var context = new EfDbContext();
// context.Set<MemberAddress>().Remove(member.HomeAddress);
// context.SaveChanges();
// }
_memberRepository.InsertOrUpdate(member);
return true;
}
}
public class UnitOfWork : IUnitOfWork
{
private readonly EfDbContext _context;
public UnitOfWork()
{
_context = new EfDbContext();
}
public IRepository<T> RepositoryFor<T>() where T : Entity
{
return new Repository<T>(_context);
}
public void Attach(Entity entity)
{
_context.Entry(entity).State = EntityState.Unchanged;
}
public void SetContextState(Entity entity, EntityState state)
{
_context.Entry(entity).State = state;
}
public void Save()
{
_context.SaveChanges();
}
}