У меня были похожие проблемы, которые возникали в EF6 (работал в EF4 без транзакций, EF 4 использовал неявные транзакции с правильной областью действия).
Простое создание новой сущности и ее сохранение не помогло в моем случае (см. Комментарии к другим ответам, у них были похожие проблемы с использованием dc.SaveChanges()
только для автоматического обновления).
Рассмотрим следующий код (CustomerId
- это первичный ключ с автоинкрементом):
public void UpdateCustomer(string strCustomerName, string strDescription)
{
using (var transaction = CreateTransactionScope())
{
MyCustomer tbl=null;
Func<MyCustomer, bool> selectByName=(i => i.CustomerName.Equals(strCustomerName));
var doesRecordExistAlready = dc.MyCustomers.Any(selectByName);
if (doesRecordExistAlready)
{
// Updating
tbl=dc.MyCustomers.Where(selectByName).FirstOrDefault();
tbl.Description=strDescription;
}
else
{
// Inserting
tbl=new MyCustomer();
var maxItem=
dc.MyCustomers.OrderByDescending(i => i.CustomerId).FirstOrDefault();
var newID = maxItem==null ? 1 : maxItem.CustomerId+1;
tbl.CustomerId=newID;
tbl.CustomerName=strCustomerName;
tbl.Description=strDescription;
dc.MyCustomers.AddObject(tbl);
}
dc.SaveChanges(); // save all changes consistently
transaction.Complete(); // commit
}
}
И вспомогательная функция для создания правильного контекста транзакции:
// creates the right transaction scope
public static System.Transactions.TransactionScope CreateTransactionScope()
// needs to add ref: System.Transactions
{
var transactionOptions = new TransactionOptions
{
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted,
Timeout = new TimeSpan(0,0,10,0,0) //assume 10 min is the timeout time
};
var scopeOption=TransactionScopeOption.RequiresNew;
var scope = new System.Transactions.TransactionScope(scopeOption,
transactionOptions);
return scope;
}
Хитрость здесь в том, чтобы разрешить чтение незафиксированным - следовательно, вы можете запросить максимальный идентификатор и добавить 1 к идентификатору.Чего я не смог добиться, так это позволить SQL-серверу автоматически генерировать идентификатор, потому что EF позволяет мне не пропускать CustomerId
при создании.
Чтобы узнать больше об объеме транзакции, смотрите здесь.