Несколько/одиночный экземпляр Linq to SQL DataContext

У меня есть проект с несколькими различными классами, которые запрашивают и изменяют данные в общем наборе таблиц. Я создал файл .dbml, который предоставляет нам класс DataContext. Мой вопрос заключается в том, должен ли один экземпляр DataContext использоваться всеми объектами или использовать несколько экземпляров в безопасном режиме. Я также задаюсь вопросом о безопасности потоков в случае одного DataContext и должен ли синхронизироваться доступ к ним.

Ответ 1

Rick Strahl имеет приятную статью о ваших вариантах: http://www.west-wind.com/weblog/posts/246222.aspx.

См. также: LINQ to SQL - где живет ваш DataContext?.

Вам может потребоваться несколько другая стратегия для каждого типа развертывания - веб-сайт, рабочий стол, служба Windows...

Подведены ваши варианты:

  • Глобальный DataContext - опасный в многопоточных средах (включая веб-приложения). Помните, что члены экземпляра не гарантируются потокобезопасностью (от Bradley Grainger answer выше).
  • DataContext для потока - сложный. Если ваш DataContext отслеживает изменения, вы должны быть уверены в том, что они сбросят их в соответствующее время. Создание, хранение и извлечение DataContext - это боль.
  • DataContext на атомное действие - вы теряете возможность отслеживать изменения, так как один DataContext создает объект, а другой обновляет или удаляет его. Прикрепление объекта данных к новому DataContext может работать не так, как вы ожидаете.
  • DataContext для объекта данных - кажется неэлегантным, потому что вы должны суетиться с DataContext при создании экземпляра (создавать и прикреплять) и обновлять/удалять (вытащить его из объекта данных и использовать его).

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

Ответ 2

Я использую новый экземпляр DataContext для каждой транзакции.

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

Если вам нужен элемент дольше, чем для транзакции, вы можете отделить его от DataContext, клонировав элемент, и позже можете подключить его к новому и новому DataContext с помощью Attach().
Я даже могу клонировать элемент, отправлять его по сети с помощью WCF, возвращать его в какой-то более поздний вызов, присоединять его к новому DataContext и сохранять изменения (конечно, для этого мне нужен столбец timestamp).

Ответ 3

Класс DataContext достаточно лёгкий, чтобы вы могли создавать его снова и снова. Это упрощает процесс доступа к объектам объектов в рамках одного метода. Если вам нужно получить доступ к тем же объектам LINQ из разных классов и методов, сохраняя при этом их привязку к DataContext для отслеживания, также можно сохранить один экземпляр.

Ответ 4

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

Вот почему я использую объект контекста данных для каждого из моих классов - у моего класса User есть собственный контекст данных, мой класс Application имеет его собственный и т.д.

Этот шаблон устраняет большинство проблем с выполнением откатов в моих проектах.

Ответ 5

Я всегда слышал, что вы должны использовать один экземпляр DataContext. Обычно я создаю экземпляр singleton моего DC в моем классе бизнес-логики и использую его для всех моих запросов linq.

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