Подходят ли когда-либо несколько классов DataContext?

Чтобы полностью использовать LinqToSql в приложении ASP.net 3.5, необходимо создать классы DataContext (что обычно делается с помощью конструктора в VS 2008). С точки зрения пользовательского интерфейса DataContext - это дизайн разделов вашей базы данных, которые вы хотите открыть через LinqToSql, и является неотъемлемой частью настройки функций ORM LinqToSql.

Мой вопрос: я создаю проект, который использует большую базу данных, в которой все таблицы каким-то образом связаны между собой через внешние ключи. Моя первая идея - создать один огромный класс DataContext, который моделирует всю базу данных. Таким образом, я мог бы теоретически (хотя я не знаю, понадобится ли это на практике) использовать соединения внешнего ключа, которые генерируются через LinqToSql, чтобы легко переходить между связанными объектами в моем коде, вставлять связанные объекты и т. Д.

Однако, поразмыслив, я теперь думаю, что имеет смысл создать несколько классов DataContext, каждый из которых относится к определенному пространству имен или логическому взаимосвязанному разделу в моей базе данных. Меня больше всего беспокоит то, что постоянное создание и удаление одного огромного класса DataContext для отдельных операций, относящихся к определенным областям базы данных, приведет к ненужному наложению на ресурсы приложения. Кроме того, легче создавать файлы DataContext меньшего размера и управлять ими, чем одним большим. Я бы потерял то, что были бы некоторые удаленные разделы базы данных, по которым нельзя было бы перемещаться через LinqToSql (даже если цепочка отношений связывает их в реальной базе данных). Кроме того, будут некоторые классы таблиц, которые будут существовать более чем в одном DataContext.

Любые мысли или опыт относительно того, подходят ли несколько DataContexts (соответствующих пространствам имен БД) вместо (или в дополнение к) одного очень большого класса DataContext (соответствующего всей БД)?

Ответов (5)

Решение

Я не согласен с ответом Джона. DataContext (или Linq to Entities ObjectContext) - это скорее «единица работы», чем соединение. Он управляет отслеживанием изменений и т. Д. См. Описание в этом сообщении в блоге:

Время жизни LINQ to SQL DataContext

Четыре основных момента этого сообщения в блоге заключаются в том, что DataContext:

  1. Идеально подходит для единичного подхода.
  2. Также разработан для работы с серверами без сохранения состояния.
  3. Не предназначен для длительного использования
  4. Should be used very carefully after
    any SumbitChanges() operation.
    

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

Я думаю, что Джон прав.

«Меня больше всего беспокоит то, что постоянное создание и удаление одного огромного класса DataContext для отдельных операций, относящихся к определенным областям базы данных, приведет к ненужному наложению на ресурсы приложения»

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

@Evan «Контекст данных (или Linq to Entities ObjectContext) - это скорее« единица работы », чем соединение». Именно поэтому у вас не должно быть более одного контекста данных. Зачем вам нужно больше одной «единицы работы» за раз?

Я не согласен с принятым ответом. В заданном вопросе система имеет одну большую базу данных с сильными отношениями внешнего ключа почти между каждой таблицей (также в том случае, когда я работаю). В этом сценарии разбиение его на более мелкие DataContexts (DC) имеет два непосредственных и основных недостатка (оба упомянуты в вопросе):

  1. Вы теряете связи между некоторыми таблицами. Вы можете попытаться выбрать границы своего DC с умом, но в конечном итоге вы столкнетесь с ситуацией, когда было бы очень удобно использовать связь из таблицы в одном DC к таблице в другом, и у вас не получится.
  2. Некоторые таблицы могут отображаться в нескольких контроллерах домена. Это означает, что если вы хотите добавить специфичные для таблицы вспомогательные методы, бизнес-логику или другой код в частичные классы, эти типы не будут совместимы с DC. Вы можете обойти это, унаследовав каждый класс сущности от его собственного конкретного базового класса, что становится беспорядочным. Кроме того, изменения схемы необходимо будет продублировать на нескольких контроллерах домена.

Теперь это существенные недостатки. Есть ли достаточно большие преимущества, чтобы их преодолеть? В вопросе упоминается производительность:

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

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

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

Кроме того, концепция единицы работы не имеет отношения к исходному вопросу. Единица работы , как правило , относится к тому, как много работы одного DC экземпляр делает, не так, как много работы постоянного тока класса является способным делать.

По моему опыту работы с LINQ to SQL и LINQ to Entities, DataContext является синонимом подключения к базе данных. Поэтому, если вам нужно было использовать несколько хранилищ данных, вам нужно было бы использовать несколько DataContexts. Моя интуиция такова, что вы не заметите большого замедления работы с DataContext, охватывающим большое количество таблиц. Если бы вы это сделали, вы всегда могли бы логически разделить базу данных в точках, где вы можете изолировать таблицы, которые не имеют никакого отношения к другим наборам таблиц, и создать несколько контекстов.

Я спорил над тем же вопросом, когда устанавливал LINQ to SQL поверх устаревшей БД. Наша база данных немного огромна (150 таблиц), и после некоторых размышлений и экспериментов я решил использовать несколько DataContexts. Будет ли это считаться антипаттерном, еще неизвестно, но пока это делает жизнь управляемой.