2017-07-24 16 views
6

Tôi đang sử dụng Entity Framework 6 và ObjectCache để cache một số thực thể không thay đổi thường xuyên. Nhưng tôi đã gặp lỗi khi cố gắng lưu các thực thể được lưu trong bộ nhớ cache vì chúng được lấy ra từ một ngữ cảnh khác. Trước khi lưu, tôi xác minh và trạng thái của đối tượng đã được tách ra nhưng không thể thoát khỏi lỗi đó cho đến khi tôi đã làm điều này:Entity Framework 6 và ObjectCache: lưu các vấn đề

public void Save(Product obj) 
{ 
    var objInDb = dbContext.Products.Find(obj.Id); 

    if (objInDb == null) 
    { 
     dbContext.Products.Add(obj); 
     dbContext.SaveChanges(); 
    } 
    else 
    { 
     dbContext.Entry(objInDb).CurrentValues.SetValues(obj); 
     dbContext.Entry(objInDb).State = EntityState.Modified; 
     dbContext.SaveChanges(); 
    } 
} 

lỗi gốc đã được cố định sau khi thực hiện các giải pháp mô tả: Gắn một thực thể của loại 'C' không thành công vì một thực thể khác cùng loại đã có cùng giá trị khóa chính. Điều này có thể xảy ra khi sử dụng phương pháp 'Đính kèm' hoặc đặt trạng thái của một thực thể thành 'Không thay đổi' hoặc 'Đã sửa đổi' nếu bất kỳ thực thể nào trong biểu đồ có xung đột giá trị khóa. Điều này có thể là do một số thực thể mới và chưa nhận được các giá trị khóa được tạo bởi cơ sở dữ liệu. Trong trường hợp này, hãy sử dụng phương thức 'Thêm' hoặc trạng thái 'Đã thêm' để theo dõi biểu đồ và sau đó đặt trạng thái của các thực thể không mới thành 'Không thay đổi' hoặc 'Đã sửa đổi' khi thích hợp.

Mã ban đầu là:

if (obj.Id == 0) 
{ 
    context.Products.Add(obj); 
} 
else 
{ 
    context.Entry(obj).State = EntityState.Modified; 
} 

context.SaveChanges(); 

Có cách nào tốt hơn để xử lý này? Tôi thực sự không thích bỏ qua bộ nhớ cache của tôi và nhấn DB để có được đối tượng bởi vì nó có vẻ không cần thiết cho tôi.

+0

Mã ban đầu không hoạt động sau đó là gì? – DavidG

+0

Tôi vừa thêm mã gốc vào câu hỏi của mình. –

+0

Bạn đã bật 'Cấu hình.ProxyCreationEnabled' trong ngữ cảnh chưa? Tôi đoán là bạn đang lưu trữ proxy trong bộ nhớ cache của bạn chứ không phải là loại thực thể thực tế. – DavidG

Trả lời

0

Tôi nghĩ cách duy nhất để không "đánh" de db sẽ giống như sau. Xin lưu ý rằng, dựa trên ngoại lệ đầu tiên của bạn, bạn đã "đánh" db cho thực thể này ở một nơi khác.

if (obj.Id == 0) 
{ 
    context.Products.Add(obj); 
} 
else 
{ 
    var localProduct = context.Products.Local.FirstOrDefault(x => x.Id == obj.Id); 
    if (localProduct == null) 
    { 
     context.Entry(obj).State = EntityState.Modified; 
    } 
    else 
    { 
     context.Entry(localProduct).CurrentValues.SetValues(obj); 
    } 
} 
context.SaveChanges(); 
Các vấn đề liên quan