LINQ Вставляет без столбца IDENTITY - PullRequest
0 голосов
/ 11 августа 2009

Я использую LINQ, но в моих таблицах базы данных нет столбца IDENTITY (хотя они используют столбец суррогатного идентификатора первичного ключа)

Может ли это работать?

Чтобы получить значения идентификаторов для таблицы, существует хранимая процедура GetIDValueForOrangeTable (), которая просматривает таблицу SystemValues ​​и увеличивает ID в ней. Можно ли как-нибудь получить LINQ для получения значения ID из этой таблицы SystemValues ​​на вставке, а не встроенной IDENTITY?

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

Приветствие Дункан

Ответы [ 2 ]

1 голос
/ 11 августа 2009

Вы очень оправданы в своей заботе. Если два пользователя пытаются вставить одновременно, оба могут получить одно и то же число, если вы не сделаете, как описано в marc_s, и не добавите это в транзакцию. Однако, если транзакция не распространяется на всю вставку, а также на таблицу, содержащую значения идентификатора, у вас могут остаться пробелы, если внешняя вставка завершится неудачно (она получила значение, но затем по какой-то другой причине не вставила запись). Поскольку большинство людей делают это, чтобы избежать пробелов (что в большинстве случаев является ненужным требованием), это усложняет жизнь и все же может не достичь результата. Использование поля идентичности почти всегда является лучшим выбором.

1 голос
/ 11 августа 2009

Конечно, вы можете сделать это с помощью LINQ, а также безопасно:

  • Оберните доступ к базовой таблице SystemValues ​​в функции «GetIDValue ..... ()» в TRANSACTION (а не с уровнем изоляции READUNCOMMITTED!), Тогда один и только один пользователь сможет получить доступ к этой таблице на любом данное время, и вы сможете безопасно распространять удостоверения личности
  • вызовите этот сохраненный процесс из LINQ непосредственно перед сохранением вашей сущности и сохраните идентификатор, если вы имеете дело с новой сущностью (если идентификатор еще не установлен)
  • сохранить вашу сущность в базе данных

Это должно сработать - не уверен, если это будет быстрее и эффективнее, чем позволить базе данных справиться с работой - но это должно работать - и безопасно.

Марк

UPDATE:

Примерно так (адаптироваться к вашим потребностям) будет работать безопасно:

CREATE PROCEDURE dbo.GetNextTableID(@TableID INT OUTPUT)
AS BEGIN
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED

    BEGIN TRANSACTION 

    UPDATE SystemTables
    SET MaxTableID = MaxTableID + 1
    WHERE ........ 

    SELECT
        @TableID = MaxTableID 
    FROM    
        dbo.SystemTables

    COMMIT TRANSACTION
END

Что касается производительности - до тех пор, пока у вас есть разумное число (возможно, менее 50) одновременно работающих пользователей, и если эти таблицы SystemTables не используются для чего-то еще, то они должны работать нормально.

...