Tôi có vấn đề tương tự, mà xảy ra ở EF6 (đã làm việc trong EF4 mà không giao dịch, EF 4 sử dụng các giao dịch ngầm với phạm vi bên phải).
Chỉ cần tạo một thực thể mới và lưu nó không giúp ích trong trường hợp của tôi (xem nhận xét của các câu trả lời khác, họ có vấn đề tương tự với việc sử dụng dc.SaveChanges()
chỉ để tự động cập nhật).
Xét đoạn mã sau (CustomerId
là chìa khóa chính với auto-increment):
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
}
}
Và chức năng helper để tạo ra bối cảnh giao dịch đúng là:
// 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;
}
Bí quyết là ở đây , để cho phép đọc không được cam kết - do đó bạn có thể truy vấn ID tối đa và thêm 1 vào id. Những gì tôi đã không thể đạt được là để cho máy chủ SQL tạo ID tự động, bởi vì EF cho phép tôi không bỏ qua các CustomerId
khi tạo.
Để đọc thêm về phạm vi giao dịch, look here.
Yeah nói chung từ các mảnh VS2010 tạo ra bạn sẽ phải thiết lập giá trị StoreGenerated trong khối lớn hàng đầu của xml. Bạn đang nhận được nhiều khóa chính vì trừ khi bạn thay đổi điều đó, EF sẽ tạo ID cho bạn, là 0. – Rangoric
Thật điên rồ khi họ chưa sửa lỗi phổ biến này. Đó là phiên bản 4, đến với đội EF !! – arviman
Rất nhiều lần, mọi người quên đánh dấu cột bằng giá trị Nhận dạng và giá trị gia tăng tự động. EF thực hiện việc này từ DB. – arviman