LINQ: Невозможно вставить строку с повторяющимся ключом в объект 'dbo.tblOutstandingCompletions' с уникальным индексом - PullRequest
3 голосов
/ 18 декабря 2008

У меня есть приложение (ASP.NET 3.5), которое позволяет пользователям при необходимости перезапускать определенный процесс. Процесс вставляет записи в таблицу MS SQL. У меня есть вставка в Try / Catch и игнорирую улов, если запись уже существует (ошибка в заголовке будет действительной). Это прекрасно работало с использованием ADO, но после того, как я перешел на LINQ, я заметил интересную вещь. Если при повторном запуске процесса уже есть записи в таблице, любые новые записи будут отклонены с той же ошибкой, даже если не было существующей записи. Код выглядит следующим образом:

            Dim ins = New tblOutstandingCompletion
            With ins
                .ControlID = rec.ControlID
                .PersonID = rec.peopleID
                .RequiredDate = rec.NextDue
                .RiskNumber = 0
                .recordType = "PC"
                .TreatmentID = 0
            End With

            Try
                ldb.tblOutstandingCompletions.InsertOnSubmit(ins)
                ldb.SubmitChanges()
            Catch ex As Exception
                ' An attempt to load a duplicate record will fail
            End Try

DataContext для базы данных был установлен во время загрузки страницы.

Я решил проблему, переопределив DataContext перед каждой вставкой:

        ldb = New CaRMSDataContext(sessionHandler.connection.ToString)
        Dim ins = New tblOutstandingCompletion

Хотя я решил проблему, я хотел бы знать, может ли кто-нибудь объяснить ее. Без переопределения DataContext приложение работает отлично, если нет повторяющихся записей.

С уважением Джеймс

Ответы [ 3 ]

2 голосов
/ 18 декабря 2008

Я видел очень похожую проблему в моем коде, когда столбец идентификаторов был не автоинкрементным столбцом int, а GUID со значением по умолчанию newguid () - в основном LINQ не разрешал базе данных создавать GUID но вставив вместо этого Guid.Empty, и вторая (или более поздняя) попытка (правильно) выдаст эту ошибку.

Я закончил тем, что сам создал новый GUID во время вставки. Более подробную информацию можно увидеть здесь: http://www.doodle.co.uk/Blogs/2007/09/18/playing-with-linq-in-winforms.aspx

Это позволило мне вставить несколько записей с одним и тем же DataContext.

Кроме того, вы пытались вызывать InsertOnSubmit несколько раз (по одному разу для каждой новой записи), но только один раз вызывать SubmitChanges?

1 голос
/ 01 мая 2011

gfrizzle, кажется, прямо здесь ...

Мой код завершается с ошибкой дубликата ключа, хотя я только что запустил сохраненный процесс для усечения таблицы в базе данных. Насколько известно контексту данных, предыдущая вставка записи с тем же ключом фактически является дублирующим ключом, и возникает исключение.

Единственный способ, который я нашел, это:

        db = null;
        db = new NNetDataContext();

сразу после вызова SubmitChanges (), который выполняет предыдущие запросы InsertOnSubmit. Кажется глупым, но для меня это единственный способ, кроме редизайна кода.

1 голос
/ 18 декабря 2008

Похоже, DataContext думает, что запись была вставлена ​​в первый раз, поэтому, если вы не переопределите контекст, он отклонит вторую вставку, потому что он «знает», что запись уже существует. Переопределение контекста заставляет его фактически проверять базу данных, чтобы увидеть, есть ли она там, а это не так. Это LINQ пытается сохранить туда и обратно в базу данных. Создавая новый контекст, вы заставляете его сбрасывать то, что он «знает» о базе данных.

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