c # работа с Entity Framework на многопоточном сервере

Какова лучшая практика для работы с структурой сущностей на многопоточном сервере? Я использую структуру лицаObjectContext чтобы управлять всеми действиями с моей базой данных, теперь я знаю, что этот контекст не является потокобезопасным, поэтому сейчас, когда мне нужно использовать его для выполнения некоторых действий с БД, я окружаю егоlock заявление, чтобы быть в безопасности. Это как я должен это сделать ??

Ответы на вопрос(6)

Решение Вопроса

Не используйте уникальный контекст сlocks (без единого шаблона)Предоставлятьуслуги без гражданства (вам нужно создать экземпляр и распоряжатьсяодин контекст на запрос)Сократите время жизни контекста как можно больше.Реализуйтесистема управления параллелизмом, Оптимистичный параллелизм может быть легко реализован с помощью Entity Framework (как). Это гарантирует, что вы не перезапишете изменения в БД, когда используете устаревшую сущность

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

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

Я вижу две основные проблемы, которые часто возникают при таком подходе:

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

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

Также не беспокойтесь о производительности использования нескольких контекстов: накладные расходы на создание / удаление нового контекста для каждого запроса практически незначительны в 90% случаев использования. Помните, что создание нового контекста не обязательно создает новое соединение с базой данных (поскольку база данных обычно использует пул соединений).

 Eyal23 февр. 2012 г., 19:35
Я немного сбит с толку, я подумал, что использование одного контекста хорошо, потому что, по-моему, он делает некоторые выводы, поэтому, когда я имею дело с одной и той же сущностью в последовательных запросах, гораздо быстрее использовать тот же контекст, чем создавать новый контекст. каждый раз. Так почему же полезно использовать его таким образом, если он медленнее и еще не безопасен для потоков?
 Eyal23 февр. 2012 г., 19:13
Если я создаю контекст для запроса (или для работы с БД), и у меня более одного контекста, одновременно меняющего конкретный объект из БД, это проблема?
 ken2k23 февр. 2012 г., 19:14
@Eyal У вас обычно возникают проблемы с параллелизмом. Попытка обновить одну и ту же сущность несколькими потоками одновременно будет трудно реализовать без уступок.
 Eyal27 февр. 2012 г., 16:03
Спасибо, я понимаю преимущество создания контекста для каждой работы, тогда, если я правильно понимаю, моя единственная проблема - это проблема параллелизма, и я не могу ее решить, кроме как поймать исключения и разобраться с ними?
 ken2k24 февр. 2012 г., 10:31
@Eyal Смотрите обновленный ответ

ении. Вы должны часто создавать новые ObjectContexts и утилизировать старые. Они, конечно же, не безопасны. Если вы продолжаете использовать один и тот же ObjectContext (в зависимости от времени жизни вашего приложения), легко получить исключение нехватки памяти, если вы изменяете огромные объемы данных, поскольку ссылки на изменяемые вами объекты хранятся в контексте объекта.

Нет. Как минимум, используйте контекст для потока, но я настоятельно рекомендую вам рассматривать контекст как единицу работы и, следовательно, использовать контекст для единицы работы для потока.

Это зависит от вас, чтобы определить «единицу работы» для вашего приложения. Но не используйтеlock использовать контекст в нескольких потоках. Это не масштабируется.

 jason23 февр. 2012 г., 20:00
Да, это была бы единица работы.
 Eyal23 февр. 2012 г., 19:05
Вы имеете в виду, что мне нужно создавать контекст перед каждой работой с БД и утилизировать его после того, как работа сделана? Например, когда клиент отправляет запрос на вход в систему, сервер создает контекст -> проверяет имя пользователя и пароль в БД с этим контекстом -> удаляет контекст
 Chris B. Behrens23 февр. 2012 г., 16:44
Этот. Еще один момент - теоретически ресурсы, которые вы пытаетесь сохранить, уже сохраняются путем объединения соединений.
 Eyal26 февр. 2012 г., 14:01
Хорошо, спасибо, так что плохо использую один контекст для каждой работы, но я все же пытаюсь понять, как справиться со сценарием, в котором более одного контекста одновременно изменяют конкретную сущность ...

где любой поток, пользовательский интерфейс и фон (как STA, так и MTA) могут одновременно обновлять одну и ту же базу данных. Я решил эту проблему, заново создав соединение сущностей с нуля в начале использования в любом новом фоновом потоке. Изучение экземпляра соединения сущности ConnectionString показывает руководство читателя, которое, как я полагаю, используется для связи общих экземпляров соединения. При воссоздании соединения сущностей с нуля значения guid различны для каждого потока, и никакого конфликта, по-видимому, не возникает. Обратите внимание, что сборка должна быть такой же, как и модель.

public static EntityConnection GetEntityConnection(
// Build the connection string.

  var sqlBuilder = new SqlConnectionStringBuilder();
  sqlBuilder.DataSource = serverName;
  sqlBuilder.InitialCatalog = databaseName;
  sqlBuilder.MultipleActiveResultSets = true;
  ...
  var providerString = sqlBuilder.ToString();
  var sqlConnection = new SqlConnection(providerString);

// Build the emtity connection.

  Assembly metadataAssembly = Assembly.GetExecutingAssembly();
  Assembly[] metadataAssemblies = { metadataAssembly };
  var metadataBase = @"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl";
  var dbModelMetadata = String.Format(metadataBase, objectContextTypeModelName);
  // eg: "res://*/Models.MyDatabaseModel.csdl|res://*/Models.MyDatabaseModel.ssdl|res://*/Models.MyDatabaseModel.msl"
  var modelMetadataPaths = modelMetadata.Split('|');
  var metadataWorkspace = new MetadataWorkspace(modelMetadataPaths, metadataAssemblies);
  var entityDbConnection = new EntityConnection(metadataWorkspace, sqlConnection);
  return entityDbConnection;

как будто это чрезвычайно дорогая сущность, поэтому вы создаете экземпляр один раз, а затем рассматриваете его как «фасад». Там нет необходимости делать это. Если по какой-либо причине ее связи объединяются под капотом и стоят очень мало (микросекунда? - возможно, меньше?) Полной настройки «цепочки объектов» для использования абстракции ObjectContext.

ObjectContext, очень похожий на прямое использование SqlConnection и т. Д., Предназначен для использования с методологией «как можно более поздней реализации и сброса как можно скорее».

EF дает вам некоторую безопасность в том, что у вас есть возможность проверить, есть ли у вас новейшие объекты до совершения (Optimistic Concurrency). Это не означает «потокобезопасность» как таковое, но оно выполняет то же самое, если вы уважаете правила.

текст. Насколько я знаю по книгам и статьям, я предпочитаю максимально сократить время жизни в Context. (но это зависит от вашего подхода и типа приложения, winform или web)

Пожалуйста, найдите больше информации в большой статье.http://www.west-wind.com/weblog/posts/2008/Feb/05/Linq-to-SQL-DataContext-Lifetime-Management

Хорошие книги:http://books.google.co.th/books?id=Io7hHlVN3qQC&pg=PA580&lpg=PA580&dq=DbContext+lifetime+for+desktop+application&source=bl&ots=ogCOomQwEE&sig=At3G1Y6AbbJH7OHxgm-ZvJo0Yt8&hl=th&ei=rSlzTrjAIovOrQeD2LCuCg&sa=X&oi=book_result&ct=result&resnum= 2 & вед = 0CCgQ6AEwAQ # v = OnePage & д & е = ложь

Существующее обсуждение наВремя жизни Datacontext в сценарии привязки WinForm

Ваш ответ на вопрос