İlişkinin yabancı anahtar özellikleri bir veya daha fazla non-null olduğu için değiştirilemedi
Ben GetByİd bu hatayı alıyorum() bir varlık ve MVC görünümü gelen yeni listeme alt varlıkları toplama ayarlayın.
İşlem başarısız oldu: ilişki değiştirilemedi yabancı anahtar bir veya daha fazla çünkü özellikleri non-null olur. Bir zaman değişim bir ilişki için yapılır ilgili özellik için ayarlanmış yabancı anahtar boş değer. Eğer yabancı anahtar varsa not null değerleri, yeni bir destek ilişki tanımlanmalıdır -yabancı anahtar özelliği atanmış olmalı boş olmayan bir değer, veya ilgisiz nesne silinmelidir.
Oldukça bu satırı anlamadım:
İlişki değiştirilemedi yabancı anahtar bir veya daha fazla çünkü özellikleri non-null olur.
Neden 2 varlıklar arasındaki ilişkiyi değiştirmek istiyorsunuz? Tüm uygulama süresi boyunca aynı kalmalıdır.
Özel durum oluşur kodu mevcut, üst sınıf için bir toplama basit atama değiştirilmiş çocuk sınıfları. Umarım bu alt sınıflar, yenilerini ekleme ve değişikliklerin kaldırılması için hitap eder. Varlık Çerçevesi bu işler sanırdım.
Kod satırlarını distile olabilir:
var thisParent = _repo.GetById(1);
thisParent.ChildItems = modifiedParent.ChildItems();
_repo.Save();
CEVAP
Eski çocuk öğeleri thisParent.ChildItems
tek tek el ile silmelisiniz. Varlık Çerçevesi senin için bunu yapmaz. Sonunda onları atmak istiyorsanız yaşındaki bir çocuk öğeleri ile yapmak istediğiniz ne varsa tutun ve diğer üst kuruluşlar için onları atamak için karar veremez. Varlık Çerçevesi kararını söylemelisin. Ama alt varlıkları edemiyor beri yapmak ZORUNDA bu iki kararlardan biri tek başına veritabanında herhangi bir ebeveyn (yabancı anahtar kısıtlaması nedeniyle) bir başvuru olmadan yaşamak. O hariç diyor zaten.
Edit
Ya eğer çocuk öğeleri eklenebilir yapardın, güncellenmiş ve silinmiş:
public void UpdateEntity(ParentItem parent)
{
// Load original parent including the child item collection
var originalParent = _dbContext.ParentItems
.Where(p => p.ID == parent.ID)
.Include(p => p.ChildItems)
.SingleOrDefault();
// We assume that the parent is still in the DB and don't check for null
// Update scalar properties of parent,
// can be omitted if we don't expect changes of the scalar properties
var parentEntry = _dbContext.Entry(originalParent);
parentEntry.CurrentValues.SetValues(parent);
foreach (var childItem in parent.ChildItems)
{
var originalChildItem = originalParent.ChildItems
.Where(c => c.ID == childItem.ID && c.ID != 0)
.SingleOrDefault();
// Is original child item with same ID in DB?
if (originalChildItem != null)
{
// Yes -> Update scalar properties of child item
var childEntry = _dbContext.Entry(originalChildItem);
childEntry.CurrentValues.SetValues(childItem);
}
else
{
// No -> It's a new child item -> Insert
childItem.ID = 0;
originalParent.ChildItems.Add(childItem);
}
}
// Don't consider the child items we have just added above.
// (We need to make a copy of the list by using .ToList() because
// _dbContext.ChildItems.Remove in this loop does not only delete
// from the context but also from the child collection. Without making
// the copy we would modify the collection we are just interating
// through - which is forbidden and would lead to an exception.)
foreach (var originalChildItem in
originalParent.ChildItems.Where(c => c.ID != 0).ToList())
{
// Are there child items in the DB which are NOT in the
// new child item collection anymore?
if (!parent.ChildItems.Any(c => c.ID == originalChildItem.ID))
// Yes -> It's a deleted child item -> Delete
_dbContext.ChildItems.Remove(originalChildItem);
}
_dbContext.SaveChanges();
}
Not: Bu test değil. Alt öğe koleksiyonu 5 ** türü olduğunu varsayarak. (Ben genellikle IList
var ve kod biraz başka görünüyor.) Ayrıca tüm depo soyutlamalar basit tutmak için elimden kaçırdım.
Eğer bu iyi bir çözüm olup olmadığını bilmiyorum, ama bu satırlar boyunca zor iş, bir çeşit navigasyon koleksiyonunda değişiklikler her türlü bakımı için yapılması gerektiğine inanıyorum. Mutlu de daha kolay bir şekilde görmek isterim.
Kısıtlamaları etkinleştirmek için başa...
Doğrulama, bir veya daha fazla varlıkl...
Null veya boş toplama geri dönmek için...
Doğrulama Sunucu Veritabanı Varlık Çer...
Hata mesaj 'istenen türde bir vey...