2013-07-25 38 views
22

Khi tôi đang cố gắng để xóa một bộ sưu tập (gọi .Clear) tôi nhận được ngoại lệ sau đây:Một mối quan hệ ở trạng thái Deleted

Có lỗi xảy ra trong khi tiết kiệm thực thể mà không vạch trần tính chất chính nước ngoài cho các mối quan hệ của họ . Thuộc tính EntityEntries sẽ trả về null vì một thực thể đơn lẻ không thể được xác định là nguồn của ngoại lệ. Xử lý các ngoại lệ trong khi tiết kiệm có thể được thực hiện dễ dàng hơn bằng cách phơi bày các thuộc tính khóa ngoài trong các loại thực thể của bạn. Xem InnerException để biết chi tiết.

Trường hợp ngoại lệ bên trong là:

Một mối quan hệ từ 'User_Availability' AssociationSet là trong 'Deleted' nhà nước. Với các ràng buộc bội số, một 'User_Availability_Target' tương ứng cũng phải ở trạng thái 'Đã xóa'.

tài trông như thế này:

.... 
ICollection<Availability> Availability { get; set; } 

Availability trông như thế này:

int ID { get; set; } 
User User { get; set; } 
DateTime Start { get; set; 
DateTime End { get; set; } 

Cấu hình như sau:

HasMany(x => x.Availability).WithRequired(x => x.User); 
HasRequired(x => x.User).WithMany(x => x.Availability); 

Mã gây ra vấn đề là:

user.Availability.Clear(); 

Tôi đã xem các lựa chọn thay thế khác như sử dụng DbSet để xóa mục, nhưng tôi không cảm thấy mã của mình sẽ sạch sẽ. Có cách nào để thực hiện điều này bằng cách xóa bộ sưu tập không?

Trả lời

22

Cách duy nhất mà tôi biết là làm cho nó hoạt động là xác định mối quan hệ là identifying relationship. Nó sẽ cần thiết để giới thiệu các khóa ngoại từ Availability để User như một chìa khóa nước ngoài vào mô hình của bạn ...

public int ID { get; set; } 
public int UserID { get; set; } 
public User User { get; set; } 

... và làm cho nó một phần của khóa chính:

modelBuilder.Entity<User>() 
    .HasKey(u => new { u.ID, u.UserID }); 

Bạn có thể mở rộng bản đồ của bạn để bao gồm khóa nước ngoài này (chỉ để được rõ ràng, nó không phải là cần thiết bởi vì EF sẽ nhận ra nó theo quy ước):

modelBuilder.Entity<User>() 
    .HasRequired(x => x.User) 
    .WithMany(x => x.Availability) 
    .HasForeignKey(x => x.UserID); 

(BTW: bạn cần phải cấu hình ure mối quan hệ chỉ từ một phía. Không cần phải có cả hai ánh xạ này trong câu hỏi của bạn.)

Bây giờ bạn có thể xóa bộ sưu tập với user.Availability.Clear(); và các đối tượng Availability sẽ bị xóa khỏi cơ sở dữ liệu.

+1

Cảm ơn Slauma, đã giải quyết được vấn đề của tôi. – Sam

+0

Cảm ơn bạn đã đăng bài này! Khi tôi chạy một bản cập nhật trên đối tượng con, tôi nhận được nhiều câu lệnh SET trên cùng một cột, do thuộc tính FK và thuộc tính điều hướng. Có một mẹo để chỉ tạo ra một tuyên bố SET? – Thomas

+0

@Thomas: Tôi không có đầu mối. SQL thế hệ là khá nhiều trong tay của EF và khó kiểm soát. Tôi thực sự ngạc nhiên khi bạn nhận được hai biểu thức SET cho cùng một cột FK. EF nên biết rằng tài sản FK và nav. tài sản đại diện cho cùng một cột FK và mối quan hệ. – Slauma

0

Có một mẹo. Bạn có thể xóa các đối tượng mà không cần sử dụng DbSet đặc biệt:

(this.dataContext as IObjectContextAdapter).ObjectContext.DeleteObject(entity); 

Thực hiện việc này cho từng mục trong bộ sưu tập sẵn có trước khi xóa. Bạn không cần 'xác định các mối quan hệ' theo cách này.

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