Почему LINQ 2 SQL при удалении контекста пытается получить дочерние отношения? - PullRequest
0 голосов
/ 04 ноября 2010

Я использую LINQ 2 SQL в одном из моих проектов, и у меня есть многочисленные отношения Клиент -> Документы1, Документы2, Документы3, Адрес, Счета и т. Д.

При использовании LoadWith (p => p.Documents1) ... и т. Д. У меня проблемы с производительностью, представьте себе 2000 клиентов со всеми этими многочисленными связями, загруженными в список в памяти!

С другой стороны, Документ -> Клиент - это не столько проблема, сколько его отношения.

Так что я пытаюсь удалить все LoadWith и просто оставить отношения Клиент -> Адрес. Теперь, если я иду и открываю Document1, а затем открываю своих клиентов, я получаю исключение для объекта при сериализации моих клиентов. Метод сериализации в основном выдает это исключение.

Метод сериализации:

public static T CloneObjectGraph<T>(this T obj) where T : class 
        {
            var serializer = new DataContractSerializer(typeof(T), null, int.MaxValue, false, true, null);
            using (var ms = new System.IO.MemoryStream())
            {
                serializer.WriteObject(ms, obj);
                ms.Position = 0;
                return (T)serializer.ReadObject(ms);
            }
        }

Способ получения клиентов:

public List<Customer> GetCustomers()
{
    using (MyDataContext db = new MyDataContext(MyDataContextManager.ConnectionString))
    {
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith<Customer>(p => p.Address);
        dlo.LoadWith<Customer>(p => p.Documents1);
        dlo.LoadWith<Customer>(p => p.Documents2);
        dlo.LoadWith<Customer>(p => p.Documents3);
        dlo.LoadWith<Customer>(p => p.Documents4);
        dlo.LoadWith<Customer>(p => p.Documents5);
        dlo.LoadWith<Customer>(p => p.Documents6);
        dlo.LoadWith<Customer>(p => p.Documents7);
        dlo.LoadWith<Customer>(p => p.Documents8);
        dlo.LoadWith<Customer>(p => p.Documents9);
        dlo.LoadWith<Customer>(p => p.Documents10);
        dlo.LoadWith<Customer>(p => p.Documents11);

        db.LoadOptions = dlo;

        return db.Customers.ToList();
    }
}

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

Я мог бы угадать конструктор DataContractSerializer для изменения, но я не могу сделать это правильно.

Любая помощь приветствуется!

1 Ответ

1 голос
/ 04 ноября 2010

Ваша ошибка происходит, потому что ваш метод клонирования попытается получить доступ ко всем дочерним свойствам вашего объекта.При наличии операторов LoadWith <> () эти дочерние свойства уже извлекаются из базы данных и доступны в памяти.При удалении операторов LoadWith <> () свойства будут пытаться выполнить отложенную загрузку объектов из базы данных.Поскольку вы уже закрыли соединение с базой данных, эти свойства не могут быть загружены (и вы получаете сообщение об ошибке).

Решение зависит от того, чего вы пытаетесь достичь, выполняя глубокое копирование объектов;Если эта глубокая копия действительно должна иметь дочерние свойства (DocumentsXX), то вы должны либо оставить операторы LoadWith <> (), либо вам нужно, чтобы соединение с базой данных оставалось открытым во время процесса (из двух, оставляя LoadWith <Операторы> (), вероятно, являются лучшим вариантом, поскольку они сводят к минимуму доступ к БД и в конечном итоге используют тот же объем памяти).Если в глубокую копию действительно не нужно включать эти свойства, необходимо заменить текущий процесс глубокого клонирования на, который может игнорировать эти свойства (будет работать либо созданный вручную глубокий клон, либо настроенный процесс сериализации).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...