ปัญหานี้มีการพูดคุยกันหลายครั้งใน stackoverflow แต่ฉันไม่พบคำตอบเกี่ยวกับวิธีการแก้ไขโดยใช้รูปแบบพื้นที่เก็บข้อมูลทั่วไป คำตอบทั้งหมดที่ให้มากำลังใช้ DBContext โดยตรง ในรูปแบบพื้นที่เก็บข้อมูลทั่วไป ฉันจะไม่สามารถเข้าถึง DBContext ได้โดยตรง และฉันใช้ Unity สำหรับ IOC ด้วย
นี่คือปัญหา: ฉันมีผู้ปกครองและผู้ปกครองมีคอลเลกชันลูก ฉันกำลังตั้งค่าคุณสมบัติบางอย่างบนพาเรนต์และลบลูกออกจากคอลเลกชันด้วย อย่างไรก็ตาม เมื่อฉันโทร SaveChanges()
ฉันได้รับข้อผิดพลาด
การดำเนินการล้มเหลว: ไม่สามารถเปลี่ยนแปลงความสัมพันธ์ได้เนื่องจากคุณสมบัติคีย์ต่างประเทศอย่างน้อยหนึ่งรายการไม่เป็นค่าว่าง เมื่อมีการเปลี่ยนแปลงความสัมพันธ์ คุณสมบัติคีย์ต่างประเทศที่เกี่ยวข้องจะถูกตั้งค่าเป็นค่าว่าง ถ้า Foreign-Key ไม่รองรับค่า Null จะต้องกำหนดความสัมพันธ์ใหม่ คุณสมบัติ Foreign-Key จะต้องได้รับการกำหนดค่าอื่นที่ไม่ใช่ Null หรือต้องลบออบเจ็กต์ที่ไม่เกี่ยวข้องออก
ตอนนี้ฉันไม่รู้ว่าเหตุใด EF จึงพยายามตั้งค่า FK เป็นโมฆะแทนที่จะลบบันทึก จุดประสงค์ของการตั้งค่า FK ให้เป็นโมฆะ แต่เก็บบันทึกเด็กกำพร้าไว้ในฐานข้อมูลคืออะไร
มีวิธีใดบ้างที่ฉันจะแก้ไขปัญหานี้โดยใช้รูปแบบพื้นที่เก็บข้อมูล ฉันจำเป็นต้องเปิดเผยวิธีการใหม่จากพื้นที่เก็บข้อมูลหรือไม่
เอนทิตี
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
}
บริการ
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
}
}
พื้นที่เก็บข้อมูล
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();
}
}