В Entity Framework ObjectContext.SaveChanges происходит сбой при обновлении столбца уникального ключа - PullRequest
1 голос
/ 15 октября 2011

Рассмотрим очень простую таблицу базы данных:

CREATE TABLE UkTest(
  id int NOT NULL,
  uk int NOT NULL
)
Primary Key on id
Unique Key on uk

Затем добавьте 2 строки:

INSERT INTO UkTest (id,uk) VALUES(1,1);
INSERT INTO UkTest (id,uk) VALUES(2,2);

Затем проведите 2 теста.

OK

var db =  new Database1Entities();
var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);

element1.uk = 0;
element2.uk = 1;  // overrides previous element1.uk value
var count = db.SaveChanges();

Сбой (перед тестом вернуть значения великобритании в 1 и 2!):

var db =  new Database1Entities();
var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);

element2.uk = 0;
element1.uk = 2;  // overrides previous element2.uk value
var count = db.SaveChanges();
// Cannot insert duplicate key row in object 'dbo.UkTest' with unique index 'UK_UkTest'

Обратите внимание, что ObjectContext.SaveChanges() проверяет строки в порядке первичного индекса.

Есть ли способ навязать собственный порядок?

Ответы [ 2 ]

2 голосов
/ 15 октября 2011

Если вы не вызовете SaveChanges() дважды, нет, нет способа контролировать порядок операторов SQL, которые Entity Framework будет отправлять в базу данных.Вы можете заключить несколько вызовов SaveChanges() во внешнюю транзакцию, чтобы гарантировать транзакционное поведение для всей операции:

using (var scope = new TransactionScope())
{
    using (var db = new Database1Entities())
    {
        var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
        var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);

        element2.uk = 0;
        db.SaveChanges();

        element1.uk = 2;
        db.SaveChanges();
    }
    scope.Complete();
}
0 голосов
/ 17 октября 2011

Благодаря Слаума.Я нашел решение.Ключ должен хранить элементы в нескольких экземплярах ObjectContext.

public class SavingElementsWithTransactionInOwnOrder
{
    public void SaveElements ()
    {
        var db = new Database1Entities();
        var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
        element1.db = db;

        db = new Database1Entities();
        var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);
        element2.db = db;

        element2.uk = 0;
        element1.uk = 2;

        var scope = new TransactionScope();
        try{
            element2.db.SaveChanges();
            element1.db.SaveChanges();
            scope.Complete();
        }
        finally{
            scope.Dispose();
        }
    }
}

public partial class UkTest
{
    public Database1Entities db { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...