Как обрабатывать обновления детей в EF - PullRequest
2 голосов
/ 15 марта 2012

У меня есть действие

[HttpPost]
public string Edit(Member member)

и член имеет коллекцию дочерних объектов ICollection<AgeBracket> AgeBrackets.

В настоящее время я получаю все A geBrackets, связанные с участником, отмечаю всех как удаленных, затем перебираю новую коллекцию и создаю новую запись для каждого. Затем я обновляю свою родительскую сущность. Это работает, но должен быть лучший способ сделать это:

например, если бы я написал SQL, я мог бы удалить всех существующих потомков одной строкой

DELETE FROM AgeBrackets WHERE MemberId = @MemberId

В моей ситуации он делает выбор для извлечения существующих элементов, затем генерирует удаление для каждого из них, затем генерирует вставку для каждого нового дочернего элемента и затем генерирует обновление для родителя.

Вот как выглядит мой код:

IList<AgeBracket> ageBrackets = db.AgeBrackets.Where<AgeBracket>(x => x.MemberId == member.MemberId).ToList();
        foreach (AgeBracket ab in ageBrackets)
            db.Entry(ab).State = EntityState.Deleted;
        if (member.AgeBrackets != null)
        foreach (AgeBracket ab in member.AgeBrackets)
        {
            ab.MemberId = member.MemberId;                  
            db.AgeBrackets.Add(ab);
        }
        db.Entry(member).State = EntityState.Modified;

Изначально я пытался опросить существующих детей и сравнить каждого из них с новым набором, но это кажется слишком сложным.

Каков наилучший способ обновить участника и всех его детей?

1 Ответ

2 голосов
/ 15 марта 2012

Есть еще один способ сделать

var originalAgeBrackets = db.AgeBrackets.Where(x => x.MemberId == member.MemberId).ToArray();
var currentAgeBrackets = member.AgeBrackets;

foreach (var original in originalAgeBrackets) {
    // check if the original age brackets were modified ou should be removed
    var current = currentAgeBrackets.FirstOrDefault(c => c.AgeBracketId == original.AgeBracketId);

    if(current != null) {
        var entry = db.Entry(original);
        entry.OriginalValues.SetValues(original);
        entry.CurrentValues.SetValues(current);
    } else {
        db.Entry(original).State = EntityState.Deleted;
    }
}

// add all age brackets not listed in originalAgeBrackets
foreach (var current in currentAgeBrackets.Where(c => !originalAgeBrackets.Select(o => o.AgeBracketId).Contains(c.AgeBracketId))) {
    db.AgeBrackets.Add(current);
}

db.SaveChanges();

К сожалению, то, что вы хотите сделать, не имеет встроенной поддержки EF Code First.Что вам поможет, будет EntityFramework.Extended .Это позволит вам сделать что-то вроде:

db.AgeBrackets.Delete(a => a.MemberId == member.MemberId);

Вы должны позаботиться об изменениях самостоятельно.Надеюсь, это поможет вам.

...