Как получить первичный ключ из таблицы, не совершая второй поездки? - PullRequest
5 голосов
/ 18 января 2010

Как я могу получить идентификационный номер первичного ключа из таблицы без повторного посещения базы данных в LINQ To SQL?

Сейчас я отправляю данные в таблицу и совершаю еще одну поездку, чтобы выяснить, какой идентификатор был назначен новому полю (в поле идентификатора с автоматическим приращением). Я хочу сделать это в LINQ To SQL, а не в Raw SQL (я больше не использую Raw SQL).

Кроме того, вторая часть моего вопроса такова: я всегда стараюсь знать идентификатор пользователя, который находится в сети, потому что я бы скорее назвал его информацию в различных таблицах, используя их идентификатор, а не GUID или имя пользователя, которое все длинные строки. Я делаю это потому, что считаю, что SQL Server, выполняющий числовое сравнение, намного (?) Более эффективен, чем пользовательский (строка) или даже guid (очень длинная строка). Мои вопросы, я больше обеспокоен, чем я должен быть? Разве стоит всегда сохранять идентификатор пользователя (int32), скажем, в состоянии сеанса?


@ RedFilter предоставил некоторые интересные / многообещающие указания по первому вопросу, потому что на данном этапе я не могу их попробовать, если кто-то знает или может подтвердить эти изменения, которые он рекомендовал в разделе комментариев своего ответа?

Ответы [ 5 ]

12 голосов
/ 18 января 2010

Если у вас есть ссылка на объект, вы можете просто использовать эту ссылку и вызвать первичный ключ после вызова db.SubmitChanges(). Объект LINQ автоматически обновит свое поле первичного ключа (идентификатора), чтобы отразить новое, назначенное ему через SQL Server.

Пример (vb.net):

  Dim db As New NorthwindDataContext
  Dim prod As New Product
  prod.ProductName = "cheese!"
  db.Products.InsertOnSubmit(prod)
  db.SubmitChanges()
  MessageBox.Show(prod.ProductID)

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

РЕДАКТИРОВАТЬ: Если вы не делаете атомарных обновлений, вы можете добавить каждый новый продукт в отдельную коллекцию и выполнить его итерацию после вызова SubmitChanges. Хотелось бы, чтобы LINQ предоставил «украдкой из базы данных», как набор данных.

4 голосов
/ 18 января 2010

Если вы не делаете что-то необычное, вам не нужно делать ничего лишнего, чтобы получить сгенерированный первичный ключ.

Когда вы вызываете SubmitChanges в вашем текстовом данных Linq-to-SQL, он автоматически обновляет значения первичных ключей для ваших объектов.

Что касается вашего второго вопроса - может быть небольшое улучшение производительности при сканировании числового поля по сравнению с чем-то вроде varchar (), но вы увидитегораздо лучшая производительность в любом случае, гарантируя, что у вас есть правильные столбцы в вашей базе данных проиндексированы.Кроме того, в случае SQL Server, если вы создаете первичный ключ с использованием столбца идентификаторов, он по умолчанию будет иметь кластеризованный индекс поверх него.

2 голосов
/ 18 января 2010

Linq to SQL автоматически устанавливает значение идентичности вашего класса с идентификатором, сгенерированным при вставке новой записи. Просто зайдите в собственность. Я не знаю, использует ли он отдельный запрос для этого или нет, никогда не использовал его, но для ORM весьма обычно требовать другого запроса, чтобы получить последний вставленный идентификатор.

Два способа сделать это независимо от Linq To SQL (который может работать с ним):

1) Если вы используете SQL Server 2005 или более позднюю версию, вы можете использовать предложение OUTPUT:

Возвращает информацию из или выражения на основе каждой строки зависит от вставки, обновления или УДАЛИТЬ утверждение. Эти результаты могут быть вернулся к обработке заявки для использования в таких вещах, как подтверждение сообщения, архивирование и другие подобные Требования к кандидатам. Кроме того, результаты могут быть вставлены в таблицу или табличную переменную.

2) В качестве альтернативы, вы можете создать пакетный оператор INSERT следующим образом:

insert into MyTable
(field1)
values
('xxx');
select scope_identity();

, который работает как минимум до SQL Server 2000.

0 голосов
/ 18 января 2010

Вызов хранимой процедуры из LINQ, которая возвращает идентификатор в качестве выходного параметра, вероятно, самый простой подход.

0 голосов
/ 18 января 2010

В T-SQL вы можете использовать предложение OUTPUT, говоря:

INSERT table (columns...)
OUTPUT inserted.ID
SELECT columns...

Так что, если вы можете настроить LINQ для использования этой конструкции для выполнения вставок, то вы, вероятно, сможете легко вернуть ее обратно. Но может ли LINQ получить значение обратно из вставки, я позволю кому-то другому ответить на это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...