2015-06-09 17 views
13

Đây là tình hình của tôi:Entity Framework: Tại sao phương thức WillCascadeOnDelete() bị bỏ qua?

public abstract class Article 
{ 
    [key] 
    public Guid Guid { get; set;} 

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

public class Download : Article 
{ 
    ... 
} 

public abstract class Category : Article 
{ 
    ... 
} 

public class DownloadCategory : Category 
{ 
    .... 
} 

Và sau đó tôi nên có một nhiều-nhiều mối quan hệ giữa Tải và DownloadCategory như thế này:

public class DownloadInCategory 
{ 
    [Key, Column(Order = 1), Required] 
    [ForeignKey("Download")] 
    Public Guid DownloadGuid { get; set; } 

    Public Download Download { get; set; } 

    [Key, Column(Order = 2), Required] 
    [ForeignKey("Category")] 
    Public Guid CategoryGuid { get; set; } 

    Public DownloadCategory Category { get; set; } 
} 

Khi tôi gọi Add-Migration sự di cư tạo ra cho DownloadInCategory thực thể là:

CreateTable("dbo.DownloadInCategories", 
c => new 
{ 
    CategoryGuid = c.Guid(nullable: false), 
    DownloadGuid = c.Guid(nullable: false), 
}) 
.PrimaryKey(t => new { t.CategoryGuid, t.DownloadGuid }) 
.ForeignKey("dbo.DownloadCategories", t => t.CategoryGuid) 
.ForeignKey("dbo.Downloads", t => t.DownloadGuid, cascadeDelete: true) 
.Index(t => t.CategoryGuid) 
.Index(t => t.DownloadGuid); 

Đây là câu hỏi của tôi: Như bạn notic e không thêm cascadeDelete: true vào một trong các khóa ngoại. TẠI SAO!!!!!!?????

Tôi nên đề cập đến rằng tôi đã không thay đổi bất kỳ Công ước modelbuilder nào. Vì vậy, lược đồ này nên thêm Casscade vào xóa trong di chuyển. Thuộc tính của tôi là [Required].

Tôi đang làm gì sai?

Thanks guys ...

Cập nhật: Xin lưu ý rằng ArticleCategory lớp là abstract. Tôi đã thay đổi các lớp học ở trên

Cập nhật 2: Không có vấn đề logic nào với lược đồ này. Nếu tôi chỉnh sửa quá trình di chuyển theo cách thủ công, nó sẽ cập nhật cơ sở dữ liệu bình thường.

Cập nhật 3: My EF Thừa kế Phương pháp là TPC

Cập nhật 4: Sau Một số điều tra và xét nghiệm Dường như vấn đề được inheritanced từ Category. Khi DownloadCategory được kế thừa từ Category, Cascade không được triển khai. nhưng khi tôi Inherit DownloadCategory trực tiếp từ Article, Cascade được triển khai. Nhưng tại sao lại một lần nữa?

+0

Nếu chỉnh sửa chuyển đổi bằng tay hoạt động tốt, nhiều này của một câu hỏi lý thuyết về lý do tại sao cascade delete không được suy ra? – jjj

+5

@jjj No. Điều này hoàn toàn thực tế theo quan điểm của tôi. Chỉnh sửa thủ công quá trình di chuyển không phải là một phương pháp hay. Trong các dự án lớn hơn như dự án tôi đang làm, Làm một điều như vậy sẽ thêm nhiều cân nhắc để bảo trì và phát triển các tính năng mới cho dự án. Tôi nghĩ rằng việc chỉnh sửa thủ công quá trình di chuyển là sai. và di chuyển phải phù hợp với lược đồ của các mô hình. – abzarak

+4

Tôi cho rằng điều đó sẽ đúng trong một thế giới lý tưởng, nơi các quy ước dựng sẵn hoàn hảo. Bạn có thể tìm hiểu mã nguồn để tìm ra lý do tại sao điều này xảy ra trong trường hợp này, nhưng tôi đoán đó là kết quả của một phím tắt để tránh chu kỳ. – jjj

Trả lời

3

tôi sẽ nghĩ rằng đây là vì:

DownloadCategory : Category : Article 

vs

Download : Article 

Điều quan trọng là trên lớp Điều. Nhiều DownloadCategories có thể sử dụng cùng một Category, do đó, nó sẽ không xếp tầng khi xóa vì điều này có thể khiến các lỗi khác của DownloadCategory bị hỏng.

Đây có thể là lỗi của khung thực thể, vì bạn đang sử dụng TPC, điều này nên được suy ra. Hãy xem this article để biết cách giải quyết.

Cụ thể các phần sau:

Trong hầu hết các trường hợp, các khung Entity có thể suy ra loại là phụ thuộc và đó là hiệu trưởng trong một mối quan hệ. Tuy nhiên, khi cần có cả hai đầu của mối quan hệ hoặc cả hai bên là tùy chọn Khung pháp nhân không thể xác định người phụ thuộc và hiệu trưởng. Khi cần có cả hai đầu của mối quan hệ, hãy sử dụng WithRequiredPrincipal hoặc WithRequiredDependent sau phương thức HasRequired. Khi cả hai kết thúc của mối quan hệ là tùy chọn, hãy sử dụng WithOptionalPrincipal hoặc WithOptionalDependent sau phương thức HasOptional.

// Configure the primary key for the OfficeAssignment 
modelBuilder.Entity<OfficeAssignment>() 
    .HasKey(t => t.InstructorID); 

modelBuilder.Entity<Instructor>() 
    .HasRequired(t => t.OfficeAssignment) 
    .WithRequiredPrincipal(t => t.Instructor); 

Bạn có thể cấu hình cascade xóa trên một mối quan hệ bằng cách sử dụng phương pháp WillCascadeOnDelete. Nếu khóa ngoại trên thực thể phụ thuộc không thể vô hiệu hóa, thì Code First đặt xóa tầng trên mối quan hệ . Nếu một khóa nước ngoài trên thực thể phụ thuộc là nullable, Mã Đầu tiên không đặt xóa tầng trên mối quan hệ và khi hiệu trưởng bị xóa, khóa ngoại sẽ được đặt thành null.

Bạn có thể loại bỏ những thác xóa ước bằng cách sử dụng:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>() 
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>() 

Các mã sau đây cấu hình mối quan hệ để được yêu cầu và sau đó vô hiệu hóa thác xóa.

modelBuilder.Entity<Course>() 
    .HasRequired(t => t.Department) 
    .WithMany(t => t.Courses) 
    .HasForeignKey(d => d.DepartmentID) 
    .WillCascadeOnDelete(false); 
+0

cảm ơn. Bài viết và lớp Thể loại là Tóm tắt. Tôi đang cập nhật câu hỏi của tôi đề cập đến chúng là Tóm tắt. – abzarak

+0

Tôi không chắc chắn điều này tạo ra sự khác biệt như thế nào? –

+0

Nếu lớp Danh mục trừu tượng, sẽ không có trường hợp nào cho Danh mục trực tiếp. Và các trường hợp là từ DownloadCategory. vì vậy "Nhiều DownloadCategories có thể sử dụng cùng Danh mục" không có ý nghĩa ở đây ... – abzarak

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