Проблемы с последней вставленной идентификацией записи с использованием типизированных DataSet и DataGridView

Я использую следующие для простого приложения базы данных:

  • SQL Server Compact Edition.sdf файл в качестве базы данных с идентификаторами первичных ключей int.
  • Типизированные DataSet и BindingSource в качестве уровня доступа к данным
  • DataGridView для отображения данных.

Моя проблема в том, что у меня проблемы с последним вставленным идентификатором записи / строки. Когда я добавляю строку в представление данных с помощью кнопки "Добавить" компонента навигатора, идентификатор новой записи / строки равен -1. Это все еще -1, даже после сохранения данных в базу данных, используя TableAdapter.Update(). Я знаю, что могу получить последний идентификатор с помощью отдельного запроса с @@identity или scope_identity(), но не совсем правильно, что вам просто нужно использовать другой запрос для обновления ваших данных, причем вручную. Я что-то здесь упускаю? Существует ли автоматический способ обновления ваших данных после сохранения в базе данных и получения идентификатора только что вставленной записи?

Кроме того, я видел опцию "обновить данные" в конструкторе набора данных -> конфигурация адаптера таблицы -> расширенное окно, но по некоторым причинам он отключен. Но я не знаю, связано ли это..

Буду признателен за любую помощь с этим..

6 ответов

Спасибо за оба ответа. Я нашел источник проблемы, к сожалению, нет решения по моему вкусу. Проблема в SQL Server Compact Edition. Так как он не поддерживает хранимые процедуры или множественный активный набор результатов (MARS), вы не можете запустить более одного SQL в одном запросе. Поэтому опция "обновить данные" отключена, что приведет к обновлению значения идентификатора фактическим значением, если оно не будет отключено. Я собираюсь изменить значение моего идентификатора первичного ключа с int на Guid, обработать событие RowInit объекта DataGridView и дать идентификатор Guid новым строкам вручную.

Вы также можете попытаться объявить свой столбец идентификаторов в качестве параметра OUTPUT в вашей хранимой процедуре.

CREATE PROCEDURE YourSP
(@ID int OUTPUT, ...

Я думаю, что вам придется вызывать databind() в вашем gridview после обновления базы данных, если вы зависите от базы данных для автоматической генерации ключа для вновь вставленной записи.

Установите IdentitySeed и IdentityIncrement в 1, и все работает.

Я нашел это в документации к Microsoft SQL Server Compact Edition:

вернуть последнюю вставленную личность:

ВЫБЕРИТЕ @@IDENTITY или ВЫБЕРИТЕ @@IDENTITY AS 'TEMPNAME'

То, что я обычно делаю с моим DTO - это что-то похожее на vb ниже

Public Sub InsertSupplier(ByVal SupplierObject As Supplier) Implements ISupplierRepository.InsertSupplier
SupplierObject.SupplierID = MyBase.ExecuteNonQueryWithReturnValue("usp_Northwind_InsertSupplier", SupplierObject.CompanyName)
End Sub

С моей хранимой процедурой, аналогичной приведенной ниже

USE [Northwind]
GO
/****** Object:  StoredProcedure [dbo].[usp_Northwind_InsertSupplier]    Script Date: 1/1/2009 10:59:01 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[usp_Northwind_InsertSupplier]
@CompanyName nvarchar(40)
AS
INSERT INTO dbo.Suppliers
VALUES (@CompanyName)

RETURN @@Identity

Просто чтобы уточнить, что делает мой 1 вкладыш в базовом классе (используя библиотеку Fyi)

Public Function ExecuteNonQueryWithReturnValue(ByVal storedProcedureName As String, ByVal ParamArray parameterValues() As Object) As Object Implements Interfaces.IRepository(Of T).ExecuteNonQueryWithReturnValue
    Dim Output As Object
    Dim db As Database = DatabaseFactory.CreateDatabase()
    Dim dbCommand As Common.DbCommand = db.GetStoredProcCommand(storedProcedureName, parameterValues)
    db.ExecuteNonQuery(dbCommand)
    Output = CType(db.GetParameterValue(dbCommand, "@RETURN_VALUE"), Object)
  Return Output
End Function
Другие вопросы по тегам