Создание идентификатора (GUID) из оператора слияния

У меня есть уровень репозитория данных, который обращается к таблице SQL в нашей базе данных с именем Form.

Я пытаюсь написать оператор Merge, который вставляет новый идентификатор, который является GUID, и обновляет запись, если идентификатор уже есть. Однако моя проблема в том, что я не знаю идентификатор, если он не создан.

Я не могу понять это. Это заставило меня задуматься, сработает ли вообще мое утверждение.

Это мой код:

conn.ExecuteScalar<Guid>(
"MERGE INTO [dbo].[Form] AS TARGET USING(VALUES(@Id,@CreatedAt,@IsComplete,@Data)) AS SOURCE(Id,CreatedAt,IsComplete,[Data]) " + 
"ON TARGET.Id = SOURCE.Id WHEN MATCHED THEN " +
"UPDATE SET CreatedAt = SOURCE.CreatedAt,IsComplete = SOURCE.IsComplete, [Data] = SOURCE.[Data] " +
"WHEN NOT MATCHED BY TARGET THEN " +
"INSERT(Id,CreatedAt,IsComplete,[Data]) " +
"VALUES(newId(),CreatedAt,IsComplete,[Data]) OUTPUT INSERTED.Id " +
"new{Id = ??????, CreatedAt = enquiry.EnquiryDate, IsComplete = 1, Data = doc});

Я не уверен, что вставить в New для Id (я оставил его с ???). Запрос — это объект, который содержит некоторые данные из другой таблицы, а документ — это XML-документ.

Любые предложения по этому поводу были бы большим подспорьем.


person Yuvi    schedule 26.01.2016    source источник
comment
В какой среде вы запускаете этот код?   -  person TT.    schedule 27.01.2016
comment
Я не знаю идентификатор, если он не создан. Разве это не просто удостоверение личности, которое вы передаете? Вы передаете идентификатор (я предполагаю, что это @Id, и если он найден, то он не создан   -  person Nick.McDermaid    schedule 27.01.2016
comment
@ТТ. Я работаю в консольном приложении   -  person Yuvi    schedule 27.01.2016
comment
Я имею в виду, из какого языка конструкция conn.ExecuteScalar<Guid>(? Я не узнаю это. Вы должны пометить свой вопрос технологиями, задействованными здесь.   -  person TT.    schedule 27.01.2016
comment
ой, извини. Это форма под названием Dapper.   -  person Yuvi    schedule 27.01.2016
comment
Dapper здесь всего лишь механизм; конечный вопрос будет таким же при использовании необработанного ado.net; так; что вы ожидаете @Id в каждом случае?   -  person Marc Gravell    schedule 27.01.2016
comment
Вы имеете в виду «если один создается» (в базе данных), а не нет? Вы можете использовать предложение OUTPUT в операторе MERGE. Вот пример: stackoverflow.com/questions/13620044/   -  person Nick.McDermaid    schedule 28.01.2016


Ответы (1)


Рассмотрите возможность переноса ответственности за создание нового идентификатора GUID в ваш репозиторий вместо того, чтобы SQL Server создавал его за вас.

Надеюсь в своем репозитории вы знаете, есть ли у вас идентификатор записи, с которой вы работаете, или это новый документ, которому еще не назначен идентификатор.

Если у вас нет идентификатора для текущего документа, используйте C# для создания нового идентификатора GUID. С этого момента код будет одинаковым независимо от того, редактируете ли вы существующую запись или создаете новую запись: вы просто передаете переменную ID в SqlCommand (в идеале как параметр).

В вашем заявлении WHEN NOT MATCHED вы можете просто ссылаться на SOURCE.Id вместо использования newId().

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

person Tim Lentine    schedule 26.01.2016