2014-07-15 37 views
7

Tôi đang sử dụng Mã EF trước. một mô hình đơn giản:Khuôn khổ thực thể DbContext .Xóa (obj) so với .Entry (obj) .State = EntityState.Deleted

item { public int Id {set; get;},... ,ICollection<ItemImages> {set; get;} } 

    itemImages { 
     public int Id {set; get; }, 
     public int ItemId {set; get; } 
      , ... , 
     public Item Item {set; get; } 
     } 

ItemConfig:EntityTypeConfiguration<Item> 
{ 
//some config statement; 
//... 
// mark child delete when parent delete: waterfall delete. 
HasRequired(rs => rs.ItemCat).WithMany(rs => rs.Items).HasForeignKey(rs => rs.ItemCatId).WillCascadeOnDelete(true); 
} 

khi thực thể xóa bằng cách Remove(), nó xóa mục và con có liên quan (hình ảnh mục hồ sơ) tốt.

_db.Item.Remove(DeleteThisObj); 
_db.SaveChanges(); 

nhưng khi đánh dấu nó để xóa:

_db.Entry(DeleteThisObj).State = EntityState.Deleted; 
_db.SaveChanges(); 

get lỗi:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

+0

có thể trùng lặp của [Entity Framework lệnh .remove() vs .DeleteObject()] (http://stackoverflow.com/questions/17723626/entity-framework- remove-vs-deleteobject) –

Trả lời

14

Nếu bạn thực sự muốn sử dụng Deleted, bạn phải làm cho các phím nước ngoài của bạn nullable, nhưng sau đó bạn sẽ kết thúc với hồ sơ mồ côi (đó là một trong những lý do chính bạn không nên làm điều đó ở nơi đầu tiên). Vì vậy, chỉ cần sử dụng Remove()

ObjectContext.DeleteObject(entity) đánh dấu thực thể là Đã xóa trong ngữ cảnh. (EntityState của nó bị xóa sau đó.) Nếu bạn gọi SaveChanges sau đó EF gửi câu lệnh SQL DELETE tới cơ sở dữ liệu. Nếu không có ràng buộc tham chiếu nào trong cơ sở dữ liệu bị vi phạm thì thực thể sẽ bị xóa, nếu không thì một ngoại lệ sẽ bị ném.

EntityCollection.Remove(childEntity) đánh dấu mối quan hệ giữa cha mẹ và childEntity là Đã xóa. Nếu bản thân childEntity bị xóa khỏi cơ sở dữ liệu và chính xác điều gì sẽ xảy ra khi bạn gọi SaveChanges phụ thuộc vào loại mối quan hệ giữa hai:

Nếu mối quan hệ là tùy chọn, tức là khóa ngoại từ con đến cha mẹ cơ sở dữ liệu cho phép NULL giá trị, nước ngoài này sẽ được thiết lập để null và nếu bạn gọi SaveChanges giá trị NULL này cho childEntity sẽ được ghi vào cơ sở dữ liệu (tức là mối quan hệ giữa hai được loại bỏ). Điều này xảy ra với câu lệnh SQL UPDATE. Không có câu lệnh DELETE nào xảy ra.

Nếu mối quan hệ là bắt buộc (FK không cho phép giá trị NULL) và mối quan hệ không xác định (có nghĩa là khóa ngoài không phải là khóa chính của đứa trẻ), bạn phải thêm trẻ em khác cha mẹ hoặc bạn phải xóa một cách rõ ràng đứa trẻ (với DeleteObject sau đó). Nếu bạn không thực hiện bất kỳ ràng buộc tham chiếu nào bị vi phạm và EF sẽ ném một ngoại lệ khi bạn gọi SaveChanges - khét tiếng "Mối quan hệ không thể thay đổi được vì một hoặc nhiều thuộc tính khóa ngoài không có giá trị" hoặc tương tự.

Nếu mối quan hệ được xác định (nhất thiết là bắt buộc vì bất kỳ phần nào của khóa chính không thể là NULL) EF cũng sẽ đánh dấu childEntity là Deleted. Nếu bạn gọi SaveChanges, câu lệnh SQL DELETE sẽ được gửi đến cơ sở dữ liệu. Nếu không có ràng buộc tham chiếu nào khác trong cơ sở dữ liệu bị vi phạm thì thực thể sẽ bị xóa, nếu không thì một ngoại lệ sẽ được ném.

Một điều đáng chú ý là thiết .State = EntityState.Deleteddoes not trigger automatically detected change.

+0

để loại bỏ() đánh dấu các bản ghi trạng thái con trong ngữ cảnh như đã xóa nhưng mục nhập (obj) .state = EntityStae.Deleted not? acctually tôi muốn nước rơi xóa – Mohammadreza

+1

@Mohammadreza Bạn có thể nghĩ về nó theo cách này, 'Remove' ảnh hưởng đến bản ghi và các mối quan hệ trong khi' xóa' chỉ ảnh hưởng đến bản ghi trong tầm tay. –

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