5

Rất đơn giản tôi đang sử dụng mã Entity Framework 4.1 trước và tôi muốn thay thế các thuộc tính [ForeignKey (..)] của mình bằng các lệnh gọi thông thạo trên modelBuilder. Một cái gì đó tương tự như WithRequired (..) và HasForeignKey (..) dưới đây mà ràng buộc một tài sản quan trọng nước ngoài rõ ràng (CreatedBySessionId) cùng với tài sản chuyển hướng liên quan (CreatedBySession). Nhưng tôi muốn làm điều này cho một mối quan hệ một đến một thay vì một đến nhiều:EF 4.1 Mã đầu tiên ModelBuilder HasForeignKey cho một mối quan hệ

modelBuilder.Entity<..>().HasMany(..).WithRequired(x => x.CreatedBySession).HasForeignKey(x => x.CreatedBySessionId) 

Ví dụ cụ thể hơn bên dưới. Điều này làm việc khá vui vẻ với thuộc tính [ForeignKey (..)] nhưng tôi muốn loại bỏ nó và cấu hình nó hoàn toàn trên modelbuilder.

public class VendorApplication 
{ 
    public int VendorApplicationId { get; set; } 

    public int CreatedBySessionId { get; set; } 
    public virtual Session CreatedBySession { get; set; } 
} 

public class Session 
{ 
    public int SessionId { get; set; } 

    [ForeignKey("CurrentApplication")] 
    public int? CurrentApplicationId { get; set; } 
    public virtual VendorApplication CurrentApplication { get; set; } 

    public virtual ICollection<VendorApplication> Applications { get; set; } 
} 

public class MyDataContext: DbContext 
{ 
    public IDbSet<VendorApplication> Applications { get; set; } 
    public IDbSet<Session> Sessions { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Session>().HasMany(x => x.Applications).WithRequired(x => x.CreatedBySession).HasForeignKey(x => x.CreatedBySessionId).WillCascadeOnDelete(false); 
     // Note: We have to turn off Cascade delete on Session <-> VendorApplication relationship so that SQL doesn't complain about cyclic cascading deletes 
    } 
} 

Dưới đây là một phiên có thể chịu trách nhiệm cho việc tạo nhiều VendorApplications (Session.Applications), nhưng một phiên đang làm việc trên nhiều nhất là một VendorApplication tại một thời điểm (Session.CurrentApplication). Tôi muốn gắn thuộc tính CurrentApplicationId với thuộc tính điều hướng CurrentApplication trong modelBuilder thay vì thông qua thuộc tính [ForeignKey (..)].

Những điều tôi đã thử

Khi bạn loại bỏ [ForeignKey (..)] thuộc tính tài sản CurrentApplication tạo ra một cột CurrentApplication_VendorApplicationId trong cơ sở dữ liệu mà không gắn liền với cột CurrentApplicationId.

Tôi đã thử một cách rõ ràng lập bản đồ các mối quan hệ bằng cách sử dụng tên cột CurrentApplicationId như dưới đây, nhưng rõ ràng điều này tạo ra một lỗi vì tên cột cơ sở dữ liệu "CurrentApplicationId" đang được sử dụng bởi các Session.CurrentApplicationId tài sản:

modelBuilder.Entity<Session>().HasOptional(x => x.CurrentApplication).WithOptionalDependent().Map(config => config.MapKey("CurrentApplicationId")); 

Có vẻ như tôi đang thiếu điều gì đó rất rõ ràng ở đây vì tất cả những gì tôi muốn làm là thực hiện thao tác tương tự mà [ForeignKey (..)] thực hiện nhưng bên trong trình tạo mô hình. Hay nó là một trường hợp mà đây là thực hành xấu và rõ ràng là trái?

Trả lời

10

Bạn cần ánh xạ mối quan hệ với tư cách một thành nhiều và bỏ qua thuộc tính thu thập trong mối quan hệ.

modelBuilder.Entity<Session>() 
    .HasOptional(x => x.CurrentApplication) 
    .WithMany() 
    .HasForeignKey(x => x.CurrentApplicationId) 
+1

Đúng vậy! Tôi đã thực sự chơi xung quanh với cấu hình đó trước đó nhưng EF đã ném một ngoại lệ đa xung đột vì vậy tôi đã xác định mối quan hệ phải là 1: 1. Tất nhiên bây giờ tôi nhận ra rằng cuộc xung đột đa dạng thực sự xảy ra bởi vì ban đầu tôi có CurrentApplicationId là không vô hiệu ... ** (mặt cọ) **. Cảm ơn sự giúp đỡ, nhiều đánh giá cao! – Walter

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