2009-04-15 5 views
7

У меня есть база данных, которая является частью схемы репликации слияния, которая имеет идентификатор GUID, так как это PK. В частности, тип данных: uniqueidentifier, значение по умолчанию (newsequentialid()), RowGUID установлено на Да. Когда я делаю InsertOnSubmit (CaseNote), я думал, что смогу оставить CaseNoteID самостоятельно, и база данных будет вводить следующий Sequential GUID, как если бы вы вручную вводили новую строку в MSSMS. Вместо этого он отправляет 00000000-0000-0000-0000-000000000000. Если я добавлю CaseNoteID = Guid.NewGuid(),, я получу идентификатор GUID, но не последовательный (я уверен).LINQ to SQL Вставить последовательный GUID

Есть ли способ позволить SQL создать следующий последовательный идентификатор в LINQ InsertOnSubmit()?

Для справки ниже приведен код, который я использую, чтобы вставить новую запись в базу данных.

  CaseNote caseNote = new CaseNote 
           { 
            CaseNoteID = Guid.NewGuid(), 
            TimeSpentUnits = Convert.ToDecimal(tbxTimeSpentUnits.Text), 
            IsCaseLog = chkIsCaseLog.Checked, 
            ContactDate = Convert.ToDateTime(datContactDate.Text), 
            ContactDetails = memContactDetails.Text 
           }; 
     caseNotesDB.CaseNotes.InsertOnSubmit(caseNote); 

     caseNotesDB.SubmitChanges(); 

Основываясь на одном из предложений ниже я включил автогенерируемые в LINQ для этого столбца и теперь я получаю следующее сообщение об ошибке ->Целевая таблица заявления DML не может иметь каких-либо включены триггеры если таковые оператор содержит предложение OUTPUT без предложения INTO. Идеи?

ответ

5

В конструкторе Linq to Sql установите для свойства Auto Generated Value значение true для этого столбца.

Это эквивалентно IsDbGenerated property для столбца. Единственное ограничение заключается в том, что вы не можете обновить значение с помощью Linq.

+0

Я попробовал это, и теперь я получаю следующее сообщение об ошибке -> Целевая таблица заявления DML не может иметь каких-либо включенных триггеров, если заявление содержит пункт OUTPUT без предложения INTO. –

+0

Почему вы приняли ответ, если он не работает? – guiomie

+0

Для меня это уже было установлено, но БД все еще пытается назначить директиву 0 по умолчанию, а не генерировать. – DCShannon

5

Из верхней части «Связанные» поле справа:

Sequential GUID in Linq-to-Sql?

Если вы действительно хотите «следующий» значение, использовать int64 вместо GUID. COMB guid гарантирует, что GUID будут заказаны.

+2

+1. Если вы хотите заказать, используйте числовой тип. Гиды были предназначены для использования в качестве уникальных идентификаторов, а не для любого способа упорядочения. –

+0

true, но это может вызвать много оттока в двух случаях: кластеризованное индексирование и производительность репликации (что похоже на проблему OP).COMB помогает в этом, но не обязательно делает их последовательными. –

+0

@ Майкл - спасибо, что указали это. Странно, что это не было одним из «предложений», когда я создал заголовок –

1

В отношении вашей целевой таблицы оператора DML не может быть активированных триггеров, если оператор содержит предложение OUTPUT без предложения INTO ", проверьте эту статью в MS KB, она выглядит как ошибка в LINQ:

http://support.microsoft.com/kb/961073

0

Существует ошибка в Linq2Sql при использовании автоматически сгенерированного (справ/последовательный Guid) первичный ключ и имеющий триггер на столе .. то есть то, что вызывает у вас ошибка. Существует исправление для этой проблемы:

http://support.microsoft.com/default.aspx?scid=kb;en-us;961073&sd=rss&spid=2855

1

Вы действительно необходимо сделать несколько вещей.

  1. Удалите присвоение свойства типа GUID
  2. Измените столбец автоматически сгенерировано
  3. Создать ограничение в базе данных по умолчанию в столбец NEWSEQUENTIALID()
  4. ли вставить на представить, как вы были до.

На вставке в таблицу будет создан идентификатор и будет последовательным. Performance comparison of NEWSEQUENTIALID() vs. other methods

+0

@ C. Tierney: Как это отличается от принятого решения? Кажется, что то же самое, только что изложено, правильно? –

0

Masstransit использует combguid:

https://github.com/MassTransit/MassTransit/blob/master/src/MassTransit/NewId/NewId.cs

это то, что вы ищете?

из википедии:

Последовательные алгоритмы

GUID, которые обычно используются в качестве первичного ключа таблицы базы данных, и с этим, часто таблица имеет кластерный индекс по этому атрибуту. Это приводит к проблемам с производительностью при вставке записей, поскольку полный случайный GUID означает, что запись может быть вставлена ​​в любом месте в таблицу, а не просто добавлена ​​ближе к ее концу. В качестве способа устранения этой проблемы, сохраняя при этом достаточную случайность , чтобы эффективно предотвращать коллизии дублированных номеров, для генерации последовательных GUID использовались несколько алгоритмов . Первый метод, , описанный Джимми Нильссоном в августе 2002 года [7] и обозначаемый как «COMB» («комбинированный указатель/временная метка»), заменяет последние 6 байтов Data4 наименее значимыми 6 байтами текущая системная дата/время. Хотя это может привести к тому, что GUID, которые генерируются не по порядку в пределах той же доли секунды, его тесты показали, что это практически не повлияло на внедрение в реальном времени. Одним из побочных эффектов этого подхода является , что при желании дату и время вставки можно легко извлечь из значения . Начиная с версии Microsoft SQL Server версии 2005 Microsoft добавила функцию к языку Transact-SQL с именем NEWSEQUENTIALID(), [8], который генерирует идентификаторы GUID, которые гарантируют, что значение увеличится, но может начинаться с более низкого числа (все еще гарантировано ), когда сервер перезагружается. Это уменьшает количество таблиц базы данных , где могут возникать вставки, но не гарантирует, что значения значения всегда будут увеличиваться. Значения, возвращаемые этой функцией , могут быть легко предсказаны, поэтому этот алгоритм не подходит для создания неясных номеров для целей безопасности или хэширования. В 2006 программист обнаружил, что функция SYS_GUID, предоставляемая Oracle , возвращала последовательные GUID на некоторых платформах, но это выглядит как , а не как функция. [9]

0

Вы должны обрабатывать методу OnCreated()

Partial Class CaseNote 
    Sub OnCreated() 
     id = Guid.NewGuid() 
    End Sub 
End Class 
Смежные вопросы