2014-11-20 18 views
15

Tôi đã tìm kiếm một chút về vấn đề của mình nhưng không thể tìm thấy bất kỳ thứ gì thực sự hữu ích.Khung thực thể - UPSERT trên các chỉ mục duy nhất

Vì vậy, vấn đề của tôi/dilema vẫn như thế này: Tôi biết rằng cơ sở dữ liệu mysql có một hệ thống chỉ số duy nhất mà có thể được sử dụng để chèn/cập nhật trong cùng một truy vấn sử dụng định dạng này: insert into t(a,b,c) values(1,1,1) on duplicate keys update b=values(b),c=values(c); và một định dạng thay thế sử dụng để thay thế một bản ghi hiện có theo chỉ mục đó.

phải trung thực những thứ tương tự như duy nhất mà tôi nhìn thấy trong MSSQL là merge nhưng tôi thực sự không thích điều đó chút nào và xác minh một truy vấn để chèn hoặc cập nhật không phải là chỉ số duy nhất dựa sau khi tất cả ...

Vậy làm thế nào tôi có thể mô phỏng UPSERT duy nhất của mysql thành Entity Framework? đây là vấn đề chính của tôi ...

Ý tôi là không nhận được bản ghi từ bộ thực thể và kiểm tra bản ghi nếu không có hoặc không để có thể chèn hoặc cập nhật;

Tôi có thể lấy nó không? Hay không? Bất kỳ gợi ý có thể hữu ích

tôi thấy this nhưng không xuất hiện vào phiên bản 6 ...

ví dụ về thực thể:

[Table("boats")] 
    public class Boat 
    { 
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
     public int id { get; set; } 
     [MaxLength(15)] 
     [Index("IX_ProviderBoat",1,IsUnique=true)] 
     public string provider_code { get; set; } 
     public string name { get; set; } 
     [Index("IX_ProviderBoat", 3, IsUnique = true)] 
     [MaxLength(50)] 
     public string model { get; set; } 
     [Index("IX_ProviderBoat", 2, IsUnique = true)] 
     [MaxLength(15)] 
     [Key] 
     public string boat_code { get; set; } 
     public string type { get; set; } 
     public int built { get; set; } 
     public int length { get; set; }    
    } 

Vì vậy, tôi muốn cập nhật/chèn dựa trên IX_ProviderBoat của tôi chỉ số duy nhất sử dụng EF

enter image description here

+1

Mô hình dữ liệu của bạn không lý tưởng cho EF. Bạn có cần phải có một 'Boat.id' cũng như ba phím duy nhất trong bảng' thuyền' của bạn? Tại sao không sử dụng 'Boat.provider_code' làm khóa chính của bạn? Ngoài ra, 'AddOrUpdate()' có sẵn trong EF6. – wahwahwah

+0

AddOrUpdate có sẵn trong EntityFramework6. Có thể bạn phải kiểm tra với các tình trạng quá tải khác như đã đề cập http://stackoverflow.com/questions/22287852/entityframework-6-addorupdate-not-working-with-compound-or-composite-primary-key –

+0

@wahwahwah 1) id chỉ là một định danh (không phải là khóa chính); 2) AddOrUpdate không hiển thị trên phiên bản 6.0.0.0 EF của tôi; 3) provider_code là khóa chính và cũng là nhóm phần chỉ mục duy nhất; – HellBaby

Trả lời

15

phương pháp AddOrUpdate là thành viên của IDBSet và là một có sẵn trong EF6.

Phương pháp AddOrUpdate không phải là một hoạt động nguyên tử, các cuộc gọi từ nhiều chủ đề không đảm bảo các chủ đề thứ hai Update thay vì Add ing một lần nữa - vì vậy bạn có thể nhận hồ sơ trùng lặp lưu trữ.

Ví dụ này đã được thử nghiệm và làm việc theo nguyện vọng của bạn:

 Boat boat = new Boat // nullable fields omitted for brevity 
     { 
      boat_code = "HelloWorld", 
      id = 1, 
      name = "Fast Boat", 
      built = 1, 
      length = 100 
     }; 

     using (BoatContext context = new BoatContext()) // or whatever your context is 
     { 
      context.Set<Boat>().AddOrUpdate(boat); // <-- IDBSet!!! 
      context.SaveChanges(); 
     } 

Nếu chúng ta thay đổi boat_code phương pháp AddOrUpdate() sẽ thêm một kỷ lục mới. Nếu boat_code là 'HelloWorld`, nó sẽ cập nhật bản ghi hiện có. Tôi tin rằng đây là những gì bạn đang tìm kiếm ...

Hy vọng điều này sẽ hữu ích!

+7

Chỉ cần bạn biết ... upsert này không phải là threadsafe ... như tôi tìm thấy trong sản xuất ngày khác ...> _ < – Aron

+0

Nó phụ thuộc vào cách bạn vứt bỏ bối cảnh của bạn ... phương pháp này không liên quan gì đến an toàn luồng. Và khi tôi nói "không có gì để làm" tôi có nghĩa là, bạn nên rõ ràng gọi GC tại một số điểm trong mã của bạn trừ khi bạn sử dụng boilerplate EF. – wahwahwah

+7

Hai luồng, hai ngữ cảnh, cùng một lệnh, cùng một lúc. Chèn trùng lặp ... rất nhiều niềm vui! Tôi đã hy vọng rằng EF sẽ sử dụng nguyên tử 'MERGE'. Nhưng nó sử dụng một lựa chọn/chèn/cập nhật. – Aron

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