2010-07-06 41 views
23

Tôi đang học Khuôn khổ thực thể theo VC# 2010.C#, khung thực thể, tăng tự động

Tôi đã tạo một bảng đơn giản cho mục đích học tập, một trong các trường là số nguyên "id", danh tính được đặt thành true . Tôi đã tạo ra Mô hình dữ liệu thực thể từ bảng đó và kết nối nó với dataGridView. Vấn đề là nó không tự động tăng - mỗi hàng được chèn muốn là id = 0 (tất nhiên là không thể, vì id phải là duy nhất)

Tôi đang làm gì sai? Tôi nên cấu hình EF hoặc bản thân SQL SQL như thế nào?

Trả lời

35

Kiểm tra trong mô hình EDMX của bạn, thuộc tính StoreGeneratedPattern của trường tự động được đặt thành "Identity". Bằng cách này, EF biết rằng các autonumbers được xử lý bởi DB.

Đây này được giải thích tốt hơn: Autonumber with Entity Framework

+0

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

+5

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

+1

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

1

Hãy chắc chắn rằng bạn đang lưu thực thể của mình trở lại cơ sở dữ liệu trước khi bạn cố đọc giá trị Id tự động tăng lên.

Id của bạn sẽ không được đặt bằng cách tự động tăng cho đến khi lần đầu tiên nó được lưu vào cơ sở dữ liệu.

+2

vấn đề là, rằng trong khi gọi SaveChanges (sau khi thêm nhiều hàng) nó ném một ngoại lệ về khóa chính nhân đôi ... – migajek

+0

@vic - Thú vị. Bạn có chắc là nó thất bại khi chèn vào bảng khóa Auto-Incremented? –

1

Có. LINQ to SQL hoạt động theo cùng một cách. Id sẽ không được đặt cho đến khi nó được lưu vào cơ sở dữ liệu. Cho đến khi bạn làm, tất cả các id sẽ là số không (như bạn đã thấy).

2

Danh tính không được thiết lập và tăng lên chỉ bằng cách thêm vào tập thực thể ... Thực thể không thực sự lưu vào db cho đến khi bạn gọi context.SaveChanges() ...

db.AddToUserSet(user);//Added to EF entity collection 
db.SaveChanges();//INSERT executed in db, Identity set and incremented. 
+6

vấn đề là, trong khi gọi SaveChanges (sau khi thêm nhiều hàng) nó ném một ngoại lệ về khóa chính trùng lặp ... – migajek

0

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.

Các vấn đề liên quan