Как эффективно освежить отношения многих ко многим - PullRequest
1 голос
/ 16 октября 2011

Допустим, у меня есть сущность A, которая имеет отношения многие ко многим с другими сущностями типа A. Итак, на сущности A у меня есть коллекция A. И допустим, я должен «обновить» эти отношения в соответствии с какой-то внешней службой. - время от времени я получаю уведомление о том, что отношения для определенной сущности изменились, и массив идентификаторов текущих связанных сущностей - некоторые отношения могут быть новыми, некоторые существующие, а некоторые уже не существуют ... Как я могу эффективно обновить свою базу данных с EF? Некоторые идеи:

  1. нетерпеливо загружайте сущность со связанными сущностями, выполняйте foreach по сбору идентификаторов из внешней службы и удаляйте / добавляйте по мере необходимости. Но это не очень эффективно - нужно загружать, возможно, сотни связанных объектов

  2. очистить текущие отношения и вставить новые. Но как ? Может быть, выполнить удаление с помощью хранимой процедуры, а затем вставить "поддельные" объекты

    a.Related.Add(new A { Id = idFromArray })
    

но можно ли это сделать в транзакции? (вызов хранимой процедуры, а затем вставка осуществляется с помощью SaveChanges)

или есть какой-то третий путь?

Thanx.

Ответы [ 2 ]

0 голосов
/ 19 октября 2011

Хорошо, решение найдено. Конечно, чистое решение EF является первым предложенным в оригинальном вопросе.

Но, если производительность имеет значение, существует третий способ, самый лучший, хотя это зависит от сервера SQL (afaik) - одна процедура с табличным параметром . Все новые связанные идентификаторы вводятся, и хранимая процедура выполняет удаление и вставку в транзакцию.

Посмотрите примеры и сравнение производительности здесь (отличная статья, на этом я основал свое решение):

http://www.sommarskog.se/arrays-in-sql-2008.html

0 голосов
/ 16 октября 2011

Что ж, «время от времени» не похоже на ситуацию, которая заставляет задуматься об улучшении производительности (если вы не имеете в виду «от миллисекунды до миллисекунды»):)

В любом случае, первый подход - правильная идея сделать это обновление без хранимой процедуры. И да, вы должны загрузить все старые связанные объекты, потому что обновление отношения «многие ко многим» происходит только при обнаружении изменений EF. Нет открытого внешнего ключа, который вы могли бы использовать для обновления отношений без загрузки свойств навигации.

Пример того, как это может выглядеть подробно, приведен здесь (свежий вопрос от вчерашнего дня):

Выбор и обновление «Многие ко многим» в Entity Framework 4

(Только последний фрагмент кода перед разделом «Редактировать» относится к вашему вопросу и к самому разделу Редактирования.)

Для вашего второго решения вы можете заключить всю операцию в созданную вручную транзакцию:

using (var scope = new TransactionScope())
{
    using (var context = new MyContext())
    {
        // ... Call Stored Procedure to delete relationships in link table

        // ... Insert fake objects for new relationships

        context.SaveChanges();
    }
    scope.Complete();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...