SORU
4 NİSAN 2011, PAZARTESİ


İ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
4 NİSAN 2011, PAZARTESİ


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Fuse

    Fuse

    21 Kasım 2005
  • sebsebdouze

    sebsebdouze

    7 ŞUBAT 2008
  • The10HourMan

    The10HourMan

    28 EYLÜL 2012