Masalah ini telah dibahas beberapa kali di stackoverflow namun saya tidak dapat menemukan jawaban tentang cara mengatasinya menggunakan pola repositori umum. Semua jawaban yang diberikan menggunakan DBContext secara langsung. Dalam pola repositori umum saya tidak akan memiliki akses langsung ke DBContext, saya juga menggunakan Unity untuk IOC.
Jadi inilah masalahnya: Saya punya orang tua dan orang tua punya koleksi anak. Saya mengatur beberapa properti pada induk dan juga menghapus anak dari koleksi. Namun ketika saya menelepon SaveChanges()
saya mendapatkan kesalahan
Operasi gagal: Hubungan tidak dapat diubah karena satu atau lebih properti kunci asing tidak dapat dibatalkan. Ketika perubahan dilakukan pada suatu hubungan, properti kunci asing terkait diatur ke nilai nol. Jika kunci asing tidak mendukung nilai null, hubungan baru harus didefinisikan, properti kunci asing harus diberi nilai lain yang bukan nol, atau objek yang tidak terkait harus dihapus.
Sekarang saya tidak tahu mengapa EF mencoba menyetel FK ke null alih-alih hanya menghapus catatan. Apa tujuan menyetel FK ke nol tetapi menyimpan catatan yatim piatu di DB.
Bagaimana cara mengatasi masalah ini menggunakan pola repositori? Apakah saya perlu mengekspos metode baru dari repositori?
Entitas
public class parent
{
public int ParentID {get;set;} //Primary Key
public string ParentName {get;set}
public ICollection<Child> Children {get;set}
}
public class Child
{
public int ChildID {get;set;} //Primary Key
public string ChildName {get;set;}
public int ParentID {get;set;} //Foreign Key
}
Layanan
public class MyService
{
private IGenericRepository _repository;
public MyService(IGenericRepository repository)
{
_repository = repository;
}
public void UpdateParent(int parentID,string parentName, int[] sourceChildIDs)
{
var p = _repository.GetQuery<Parent>()
.Include(x => x.Children)
.Where(x => x.ParentID == parentID)
.SingleOrDefault();
p.ParentName = parentName;
var childrenToDetete = new List<Child>();
foreach (var child in p.Children)
{
if (!sourceChildIDs.Contains(child.ChildID))
{
childrenToDetete.Add(child);
}
}
foreach (var child in childrenToDetete)
{
p.Children.Remove(child);
}
_repository.SaveChanges(); // i get error here
}
}
Repositori
public class GenericRepository : IGenericRepository
{
private DbContext _dbContext;
public GenericRepository(DbContext dbContext)
{
if (dbContext == null)
{
throw new ArgumentNullException("dbContext");
}
_dbContext = dbContext;
}
public TEntity Create<TEntity>() where TEntity : class
{
return _dbContext.Set<TEntity>().Create<TEntity>();
}
public TEntity Add<TEntity>(TEntity entity) where TEntity : class
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
return _dbContext.Set<TEntity>().Add(entity);
}
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
return _dbContext.Set<TEntity>();
}
public IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return GetQuery<TEntity>().Where(predicate);
}
public void Delete<TEntity>(TEntity entity) where TEntity : class
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_dbContext.Set<TEntity>().Remove(entity);
}
public void Delete<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class
{
IEnumerable<TEntity> records = GetQuery<TEntity>(criteria);
foreach (TEntity record in records)
{
Delete<TEntity>(record);
}
}
public void Update<TEntity>(TEntity entity) where TEntity : class
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_dbContext.Entry(entity).State = EntityState.Modified;
}
public int SaveChanges()
{
return _dbContext.SaveChanges();
}
}