Совет пожалуйста:Идентификация SQL Server и ключи уникального идентификатора при использовании Entity Framework

StackOverflow https://stackoverflow.com/questions/604273

Вопрос

Я занимаюсь проектированием довольно сложной системы.Одной из наших основных задач является поддержка одноранговой репликации SQL Server.Идея состоит в поддержке нескольких географически разделенных узлов.

Второстепенной проблемой было использование современного ORM на среднем уровне.Нашим первым выбором всегда был Entity Framework, главным образом потому, что разработчикам нравится с ним работать.(Им нравится поддержка LiNQ.)

Итак, вот проблема:

Имея в виду одноранговую репликацию, я остановился на использовании uniqueidentifier со значением по умолчанию newsequentialid() для первичного ключа каждой таблицы.Казалось, это обеспечивает хороший баланс между предотвращением конфликтов ключей и уменьшением фрагментации индекса.

Однако оказывается, что текущая версия Entity Framework имеет очень странное ограничение:если ключевой столбец сущности является уникальным идентификатором (GUID), то его нельзя настроить на использование значения по умолчанию (newsequentialid()), предоставленного базой данных.Уровень приложения должен сгенерировать GUID и заполнить значение ключа.

Итак, вот дискуссия:

  1. отказаться от Entity Framework и использовать другой ORM:
    • используйте NHibernate и откажитесь от поддержки LiNQ
    • используйте linq2sql и откажитесь от будущей поддержки (не говоря уже о привязке к SQL Server в БД)
  2. отказаться от GUID и перейти к другой стратегии PK
  3. разработать метод генерации последовательных GUID (COMB?) на уровне приложения

Я склоняюсь к варианту 1 с linq2sql (моим разработчикам очень нравится linq2[штуки]) и 3.Это главным образом потому, что я несколько неосведомлен об альтернативных ключевых стратегиях, которые поддерживают схему репликации, к которой мы стремимся, и в то же время сохраняют разумность с точки зрения разработчика.

Любое понимание или мнение будут очень признательны.

Это было полезно?

Решение

Другой вариант (недоступный на момент публикации) — обновиться до EF 4, который поддерживает GUID, генерируемые сервером.

Другие советы

Я поддерживаю предложение Крейга - вариант 4.

Вы всегда можете использовать столбец GUID, заполненный промежуточным уровнем, в качестве ПЕРВИЧНОГО КЛЮЧА (это ЛОГИЧЕСКАЯ конструкция).

Чтобы избежать массивного индекса (таким образом:table) фрагментация, используйте какой-либо другой ключ (в идеале столбец INT IDENTITY) в качестве КЛЮЧА КЛАСТЕРИЗАЦИИ - это физическая конструкция базы данных, которая МОЖЕТ быть отделена от первичного ключа.

По умолчанию первичный ключ является ключом кластеризации, но это не обязательно.Фактически, я улучшил производительность и радикально снизил фрагментацию, сделав именно это в базе данных, которую я «унаследовал» - добавил столбец INT IDENTITY и поместил ключ кластеризации в этот маленький, постоянно увеличивающийся, никогда не меняющийся INT - работает как шарм!

Марк

Хм?Я думаю, что ваши три варианта — ложный выбор.Рассмотрим вариант 4:

4) Используйте Entity Framework с непоследовательный, GUID, сгенерированные клиентом.

EF не видит GUID, созданные сервером БД. для новых строк, вставленных самой структурой, конечно, но вам не нужно генерировать GUID на сервере БД.Вы можете генерировать их на клиенте при создании экземпляров сущностей.Вся суть GUID в том, что не имеет значения, где вы его генерируете.Что касается GUID, сгенерированных реплицируемой БД, EF их прекрасно увидит.

Ваши GUID на стороне клиента не будут последовательными (используйте Guid.NewGuid()), но они будут гарантированно уникальными по всему миру.

Мы делаем это при доставке и производстве программного обеспечения с репликацией.Это делает работа.

Почему бы не использовать столбец идентификаторов?Если вы выполняете репликацию слиянием, вы можете запустить каждую систему с отдельного начального числа и работать в одном направлении (например,узел a начинается с 1 и добавляет 1, узел b начинается с 0 и вычитает единицу)...

Вы можете использовать хранимые процедуры, если вы действительно застряли в использовании NewSequentialID().Вы можете привязать столбцы результатов процедуры к соответствующему свойству, и после вставки GUID, сгенерированный SQL, будет возвращен обратно в объект.

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

Пошаговый пример есть на http://blogs.msdn.com/bags/archive/2009/03/12/entity-framework-modeling-action-stored-procedures.aspx что довольно просто.

используйте newseqid со своим собственным orm (это не так уж и сложно) с linq

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top