2012-04-12 42 views
13

Sử dụng phương pháp tiếp cận mã nguồn mở Entity Framework.Cách nào xung quanh việc xóa tầng sẽ đi theo mối quan hệ một-nhiều?

Giả sử tôi có hai lớp thực thể:

[Table("Objects")] 
public class DbObject : IValidatableObject 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<DbObjectProperty> Properties { get; set; } 
} 

[Table("ObjectProperties")] 
public class DbObjectProperty 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 
    public string Value { get; set; } 

    [Display(Name = "Object"), UIHint("Object")] 
    public long ObjectId { get; set; } 
    public virtual DbObject Object { get; set; } 
} 

điểm cần lưu ý ở đây:

  • DbObject chỉ có một tài sản chuyển hướng, nhưng không có cột với nước ngoài chủ chốt
  • DbObjectProperty có một chuyển hướng thuộc tính cột tương ứng với khóa ngoài
  • I t rõ ràng là nếu tôi xóa một đối tượng, tôi muốn các thuộc tính của nó đi cùng với nó, nhưng nếu tôi xóa một thuộc tính duy nhất, tôi không muốn toàn bộ đối tượng biến mất.

Trong phương pháp OnModelCreating cho bối cảnh DB, cho đến bây giờ tôi đã có sau đây để xác định mối quan hệ:

modelBuilder.Entity<DbObjectProperty>() 
    .HasRequired(op => op.Object) 
    .WithMany(obj => obj.Properties) 
    .HasForeignKey(op => op.ObjectId) 
    .WillCascadeOnDelete(false); 

Tất nhiên, điều này có nghĩa là không xóa cascaded sẽ xảy ra. Câu hỏi của tôi là: nếu tôi thay đổi điều này thành true, điều đó có làm những gì tôi muốn không? Hãy nhớ rằng nếu tôi xóa một đối tượng, tôi muốn các thuộc tính của nó đi cùng với nó, nhưng nếu tôi xóa một thuộc tính duy nhất, tôi không muốn toàn bộ đối tượng biến mất.

Mã di cư tự động tạo ra cho sự thay đổi này (từ false để true) là thế này:

DropForeignKey("ObjectProperties", "ObjectId", "Objects"); 
DropIndex("ObjectProperties", new[] { "ObjectId" }); 
AddForeignKey("ObjectProperties", "ObjectId", "Objects", "Id", cascadeDelete: true); 
CreateIndex("ObjectProperties", "ObjectId"); 

Tôi lo lắng rằng điều này dường như ngụ ý rằng việc xoá một tài sản sẽ xóa đối tượng liên quan. Nó sẽ?

Trả lời

13

Hướng của Cascading Xóa của một mối quan hệ trong cơ sở dữ liệu được xác định bởi hiệu trưởng (bảng của khóa chính/duy nhất) là gì và phụ thuộc (bảng khóa ngoại) của mối quan hệ này.

Sau đó, nếu bạn xóa hiệu trưởng, tất cả người phụ thuộc có giá trị khóa ngoài tương ứng với giá trị khóa chính/duy nhất của hiệu trưởng đó cũng sẽ bị xóa. Không có việc xóa tầng theo hướng từ người phụ thuộc đến hiệu trưởng.

Trong trường hợp của bạn, hiệu trưởng là DbObject và người phụ thuộc là DbObjectProperty vì đó là thực thể/bảng có khóa ngoại. Nó sẽ hiếm khi có ý nghĩa để xóa tầng theo cách khác - đặc biệt là trong các mối quan hệ x-to-nhiều: Nếu bạn xóa một người phụ thuộc (DbObjectProperty) và hiệu trưởng (DbObject) sẽ bị xóa tự động, một khóa ngoại ràng buộc sẽ bị vi phạm nếu có bất kỳ người phụ thuộc nào khác đề cập đến hiệu trưởng sẽ bị xóa.

Bạn không cần phải lo lắng.

+0

[Cảm ơn!] (Http://meta.stackexchange.com/questions/700/) – Timwi

+0

Quy tắc chung là, với xóa tầng, nếu xóa một bản ghi phá vỡ khoá ngoại từ một bản ghi khác, bản ghi phụ thuộc đó sẽ bị xóa quá. – orad

+0

Vì vậy, 'modelBuilder.Entity () .HasMany (p => p.Children) .WithOne (c => c.Parent)' giống với 'modelBuilder.Entity () .HasOne (c => c.Parent) .WithMany (p => p.Children) '(chúng chỉ định cùng mối quan hệ)? –

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