ASP.NET MVC 2: обновление сущности Linq-To-Sql с помощью EntitySet - PullRequest
1 голос
/ 31 марта 2010

У меня есть сущность Linq to Sql, у которой есть EntitySet. В моем представлении я отображаю сущность с ее свойствами, а также редактируемый список дочерних объектов. Пользователь может динамически добавлять и удалять эти дочерние объекты. Пока что DefaultModelBinder работает нормально, он правильно связывает дочерние объекты.

Теперь моя проблема в том, что я просто не могу заставить Linq To Sql удалить удаленные дочерние объекты, он с удовольствием добавит новые, но не удалит удаленные. Я включил каскадное удаление в отношении внешнего ключа, и дизайнер Linq To Sql добавил атрибут «DeleteOnNull = true» в отношения внешнего ключа. Если я вручную удаляю дочернюю сущность, как это:

myObject.Childs.Remove(child);
context.SubmitChanges();

Это удалит дочернюю запись из БД. Но я не могу заставить его работать для связанного с моделью объекта. Я попробовал следующее:

// this does nothing
public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities
{
    var obj2 = _repository.GetObj(id); // obj2 has 6 child entities
    if(TryUpdateModel(obj2)) //it sucessfully updates obj2 and its childs
    {
         _repository.SubmitChanges(); // nothing happens, records stay in DB
    }
    else
         .....

    return RedirectToAction("List");
}

и это выдает InvalidOperationException, у меня немецкая ОС, поэтому я не совсем уверен, что это сообщение об ошибке на английском языке, но оно говорит что-то вроде того, что для сущности нужна версия (строка метки времени?) Или нет политика проверки обновлений. Я установил UpdateCheck = "Никогда" для каждого столбца, кроме столбца первичного ключа.

public ActionResult Update(MyObject obj)
{
    _repository.MyObjectTable.Attach(obj, true);
    _repository.SubmitChanges(); // never gets here, exception at attach
}

Я много читал о подобных «проблемах» с Linq To Sql, но, похоже, большинство этих «проблем» на самом деле задумано. Так я прав в своем предположении, что это не работает, как я ожидаю, что это будет работать? Действительно ли мне нужно вручную перебирать дочерние объекты и удалять, обновлять и вставлять их вручную? Для такого простого объекта это может работать, но я планирую создавать более сложные объекты с вложенными EntitySets и так далее. Это всего лишь тест, чтобы увидеть, что работает, а что нет. Пока что я разочарован Linq To Sql (возможно, я просто не понимаю). Будет ли Entity Framework или NHibernate лучшим выбором для этого сценария? Или я столкнулся бы с той же проблемой?

1 Ответ

0 голосов
/ 31 марта 2010

Это определенно будет работать в Entity Framework, который поставляется с .NET 4 (я делаю аналогичные вещи в версии RC)

Это не объясняет исключение , но :

Вы должны утилизировать ObjectContext, который (скорее всего) обернут в вашем хранилище. Контекст кэширует элементы и должен использоваться только для одной единицы работы.

Попробуйте использовать шаблон как:

public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities
{
    using(var repository = CreateRepository())
    {
        var obj2 = _repository.GetObj(id);
        if(TryUpdateModel(obj2))
        {
             repository.SubmitChanges();
        }
        else
            .....
    }

    return RedirectToAction("List");
}

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

...