Использование SqlServer uniqueidentifier / updated date columns с Linq to Sql - лучший подход

Верно или нет, я использую уникальный идентификатор в качестве первичного ключа для таблиц в моей базе данных sqlserver. Я создал модель с использованием linq to sql (c #), однако в случае столбца identity linq to sql генерирует уникальный ключ при вставке новой записи для guid / uniqueidentifier значение по умолчанию 00000000-0000-0000-0000-000000000000.

Я знаю, что могу установить guid в своем коде: в модели linq to sql или где-то еще, или есть значение по умолчанию при создании таблицы sql server (хотя это отменяется значением, созданным в коде). Но где лучше всего разместить этот ключ, учитывая, что мои таблицы всегда будут меняться по мере развития моего решения, и поэтому я буду регенерировать свою модель Linq в Sql, когда это произойдет.

Применяется ли то же решение для столбца, в котором хранится текущий datetime (вставки), который будет обновляться с каждым обновлением?


person Richbits    schedule 29.05.2009    source источник


Ответы (3)


Как вы отметили в своем собственном сообщении, вы можете использовать методы расширяемости. Добавляя в свой пост, вы можете просмотреть частичные методы, созданные в тексте данных для вставки и обновления каждой таблицы. Пример с таблицей под названием "test" и столбцом "changeDate":

partial void InsertTest(Test instance)
{
    instance.idCol = System.Guid.NewGuid();
    this.ExecuteDynamicInsert(instance);
}

partial void UpdateTest(Test instance)
{
    instance.changeDate = DateTime.Now;
    this.ExecuteDynamicUpdate(instance);
}
person Stephan Keller    schedule 29.05.2009
comment
Спасибо, Стефан, я думаю, что это, вероятно, мой предпочтительный подход, UpdateTest (...) выглядит хорошо, однако одна проблема при использовании InsertTest поверх OnCreated - это место в жизненном цикле объекта, которое может возникнуть по отношению к другим связанным объектам. Могу ли я создать ссылки на другие объекты, используя значения по умолчанию 0, если я еще не сгенерировал guid? - person Richbits; 29.05.2009
comment
AFAIK, если ваши связанные объекты прикреплены как набор сущностей к вашему родительскому объекту, внешние ключи связанных объектов обновляются после вставки. Однако я не нахожу ничего плохого в установке guid в методе OnCreate. Я использую Insert-Method, потому что мне нужно установить уникальный непрерывный номер (например, номер счета-фактуры), который берется из пула номеров в базе данных. Для уникальных ключей я использую столбцы идентификации. - person Stephan Keller; 29.05.2009
comment
Спасибо, я попробовал это, и, похоже, все работает нормально. Я использовал исходный метод OnCreated (), но теперь изменил этот подход. - person Richbits; 29.05.2009
comment
Просто чтобы следить за этим. Этот подход не работает для Guids, поскольку для коллекции повторяющиеся ключи 0s добавляются до вызова метода вставки, поэтому возникает исключение. У меня есть другой подход, который, я думаю, я буду использовать для guids: значение sqlserver по умолчанию для newid (), затем в linqtosql установите для свойства автоматически сгенерированного значения значение true. Это нужно делать для каждого поколения модели, но это довольно просто. - person Richbits; 03.06.2009

Спасибо, я попробовал это, и, похоже, все работает нормально. У меня есть другой подход, который, я думаю, я буду использовать для guids: значение sqlserver по умолчанию для newid (), затем в linqtosql установите для свойства автоматически сгенерированного значения значение true. Это нужно делать для каждого поколения модели, но это довольно просто.

person Vefk    schedule 10.06.2011

Вы можете сделать две вещи:

  • либо просто сгенерируйте GUID в своем коде на стороне клиента C # и используйте это значение
  • создайте ограничение DEFAULT для столбца GUID в SQL Server, которое по умолчанию равно newid() для столбца - SQL Server будет УБЕДИТЬСЯ, чтобы всегда добавлять значение по умолчанию - если вы не укажете значение самостоятельно

Что касается самообновляющихся столбцов даты / времени - здесь вам, вероятно, придется использовать для этого либо логику на стороне клиента, либо, если вы хотите сделать это на SQL Server, вам придется написать триггер. Это действительно единственный способ обновлять определенный столбец каждый раз, когда обновляется строка - здесь нет ограничения «автообновление» или чего-то подобного (а ограничение по умолчанию работает только с INSERT, но не с обновлениями).

Что-то вроде этого может сработать:

CREATE TRIGGER TRG_UpdateDateTimestamp
ON (your table name)
AFTER UPDATE 
AS
    IF NOT UPDATE(DateTimeStamp)
    BEGIN
       UPDATE (yourtablename) 
       SET DateTimeStamp = GETDATE()
       WHERE EXISTS (SELECT * FROM inserted AS i 
                     WHERE i.OID = (yourtable).OID)
   END

Марк

person marc_s    schedule 29.05.2009
comment
Спасибо, Марк, проблема с кодом, сгенерированным linq to sql по умолчанию, заключается в том, что он генерирует guid 0s, поэтому значение по умолчанию, созданное sqlserver, перезаписывается (я считаю, что нашел решение для этого - я сам добавил ответ) . Хотя триггер выглядит полезным, я попробую, хотя чувствую, что мне нужно более общее решение, чтобы не писать этот код для каждой таблицы. Возможно, мне следует иметь общую таблицу обновлений с столбцами tname, id и datetime, иметь триггер для каждой таблицы для запуска общей хранимой процедуры для вставки новой записи в эту таблицу? Это жизнеспособно? - person Richbits; 29.05.2009
comment
По какой-то причине мой ответ не появляется, ответ можно найти здесь: codecadet.strongerforyou.com/post/ - person Richbits; 29.05.2009