InsertOnSubmit = Невозможно добавить объект с ключом, который уже используется - PullRequest
4 голосов
/ 13 мая 2009

Я пытаюсь вставить запись в таблицу, используя Linq, но получаю ужас Невозможно добавить объект с ключом, который уже используется ошибка

'If the same data exists for the same patient in a record less that 21 days old then drop it
Dim RecordLookup As Integer = 0
RecordLookup = (From rc In CDEvodb.RISKCHANGEs _
    Where rc.NHI = tmpNHI And _
    rc.RECDATE > Date.Now.AddDays(-21) And _
    rc.BPSYS = Convert.ToDecimal(Drow.Item("BPSYS")) And _
    rc.CHOL = Convert.ToDecimal(Drow.Item("CHOL")) And _
    rc.HDL = Convert.ToDecimal(Drow.Item("HDL"))).Count()
If (RecordLookup = 0) Then
Dim riskchange As New RISKCHANGE
    riskchange.NHI = Drow.Item("NHI")
    riskchange.RECDATE = Date.Now.Date()
    riskchange.RISK = CalculatedRisk
    riskchange.BPSYS = Drow.Item("BPSYS")
    riskchange.CHOL = Drow.Item("CHOL")
    riskchange.HDL = Drow.Item("HDL")

    Try
        CDEvodb.RISKCHANGEs.InsertOnSubmit(riskchange)
    Catch ex As Exception
        myLogging.OutputError("<" & DateTime.Now.ToString & "> " & "Error - creating risk change record in dataset for patient " & Drow.Item("NHI").ToString() & " - " & ex.Message)
    End Try

End If

В основном я ищу в таблице подходящую запись (не включая поле Identity), которой менее 21 дня. Если я не нахожу его, я создаю экземпляр строки и устанавливаю его для вставки.

Функция SubmitChanges вызывает несколько строк вниз.

Drow - это DataRow из набора данных, ранее заполненный с использованием соединения SQLClient (причина в том, что я еще не полностью перешел на Linq, сейчас просто выполняю новые функции).

Приветствия заранее.


это скрипт создания таблицы:

USE [CDEvolution]

GO

/ ****** Объект: Таблица [dbo]. [RISKCHANGES] Дата сценария: 13.05.2009 14:40:15 ****** /

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_PADDING ON

GO

CREATE TABLE [dbo]. [RISKCHANGES] (

[NHI] [varchar](7) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,

[RECDATE] [datetime] NOT NULL,

[RISK] [numeric](15, 0) NOT NULL,

[BPSYS] [numeric](15, 0) NOT NULL,

[CHOL] [numeric](15, 1) NOT NULL,

[HDL] [numeric](15, 1) NOT NULL,

[POSTED] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

[IDENTITY] [uniqueidentifier] NOT NULL CONSTRAINT [DF_RISKCHANGES_IDENTITY]  

DEFAULT (newid ()),

CONSTRAINT [PK_RISKCHANGES] ПЕРВИЧНЫЙ КЛЮЧ КЛАСТЕРНЫЙ

(

[IDENTITY] ASC

) С (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [ПЕРВИЧНЫЙ]

) ВКЛ [ПЕРВИЧНЫЙ]

* * GO тысяча сорок-девять

SET ANSI_PADDING OFF

Ответы [ 3 ]

9 голосов
/ 13 мая 2009

Если вы обновляете свой DBML, добавьте это ( IsDbGenerated = "true" ) к члену PK:

    <Column Name="[IDENTITY]" Member="IDENTITY" Type="System.Guid" 
            DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" 
            CanBeNull="false" IsDbGenerated="true"/>

Это позволит SQL назначить значение по умолчанию (newid ()).

В противном случае он отправит неинициализированный гид ('00000000-0000-0000-0000-000000000000'), который, по моему мнению, является основной причиной проблемы.

Другим вариантом может быть расширение частичного класса и инициализация GUID в событии OnCreated () (которое не использует столбец newid () по умолчанию, но действительно решает проблему)

    partial class RISKCHANGE
    {
        partial void OnCreated()
        {
            _IDENTITY = Guid.NewGuid();
        }
    }

Обратите внимание, что для существующих объектов (заполняемых запросом) это значение будет перезаписано правильным значением при обработке OnLoaded ().

0 голосов
/ 13 мая 2009

Какой у вас первичный ключ? И есть ли у вас какие-либо другие ключи / ограничения на столе? Это, вероятно, один из тех, кто вызывает проблему. Я предлагаю расширить поиск подходящих записей или изменить ограничения.

0 голосов
/ 13 мая 2009

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

Являются ли какие-либо из свойств, которые вы устанавливаете для нового объекта смены риска, свойством первичного ключа?

Кроме того, что еще вы делаете перед вызовом SubmitChanges ()?

ура

EDIT:

спасибо Кевину. Что здесь происходит с этой строкой?

[IDENTITY] [uniqueidentifier] NOT NULL CONSTRAINT [DF_RISKCHANGES_IDENTITY]

какие ограничения у вас на ПК ...? Почему это не выглядит так:

[IDENTITY] [int] IDENTITY(1,1) NOT NULL

EDIT Привет, Кевин. Я думаю, проблема в том, что вы не установили свой PK в качестве спецификатора идентификации, и поэтому он не увеличивает значение PK автоматически.

Чтобы устранить проблему, либо заново создайте таблицу, изменив эту строку:

[IDENTITY] [uniqueidentifier] NOT NULL CONSTRAINT [DF_RISKCHANGES_IDENTITY]

на это:

[IDENTITY] [int] IDENTITY(1,1) NOT NULL

или, если вы используете Mangement Studio, просто зайдите в дизайн этой таблицы. Перейдите к свойствам этого поля и в окне свойств (которое обычно отображается ниже) задайте для «Idenity Specification» (Is Identity) значение YES.

Не забудьте также обновить LINQ 2 SQL DBML

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