2013-03-10 31 views
5

Tôi có 3 lớp trong mô hình của tôi như bạn có thể thấy bên dưới.Xác định nhiều mối quan hệ trong khung thực thể mã đầu tiên

[Table("UserProfile")] 
public class UserProfile 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string UserName { get; set; } 

    public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; } 
} 

[Table("MartialArt")] 
public class MartialArt 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Description { get; set; } 

    public string IconPath { get; set; } 

    public string ImagePath { get; set; } 

    public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; } 
} 

public class MartialArtUserProfile 
{ 
    public int UserProfileId { get; set; } 
    public UserProfile UserProfile { get; set; } 

    public int MartialArtId { get; set; } 
    public MartialArt MartialArt { get; set; } 
} 

Và tôi có một lớp cấu hình cho nhiều mối quan hệ như sau:

public class MartialArtUserProfileConfiguration : EntityTypeConfiguration<MartialArtUserProfile> 
{ 
    public MartialArtUserProfileConfiguration() 
    { 
     HasKey(a => new { a.MartialArtId, a.UserProfileId }); 

     HasRequired(a => a.MartialArt) 
      .WithMany(s => s.MartialArtUserProfiles) 
      .HasForeignKey(a => a.MartialArtId) 
      .WillCascadeOnDelete(false); 

     HasRequired(a => a.UserProfile) 
      .WithMany(p => p.MartialArtUserProfiles) 
      .HasForeignKey(a => a.UserProfileId) 
      .WillCascadeOnDelete(false); 
    } 
} 

Sau khi xác định các đối tượng của tôi một mối quan hệ khi tôi cố gắng chạy Update-Cơ sở dữ liệu trong Package Manager Console , nó nói:

Đã phát hiện một hoặc nhiều lỗi xác thực trong quá trình tạo mô hình:

\ tSystem.Data.Entity.Edm.EdmEntityType:: EntityType 'MartialArtUserProfile' không có khóa được xác định. Xác định khóa cho EntityType này. \ tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'MartialArtUserProfiles' dựa trên loại 'MartialArtUserProfile' không có khóa được xác định.

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

Cảm ơn trước,

+0

bạn có thực sự cần lớp MartialArtUserProfile hoặc bạn chỉ sử dụng nó để tạo mối quan hệ nhiều-nhiều? –

+0

Tôi chỉ sử dụng nó để tạo mối quan hệ nhiều-nhiều. @Sniffer – anilca

Trả lời

8

Nếu tôi hiểu bạn chỉ đơn giản là cố gắng để tạo ra một nhiều cho nhiều người với một bảng bắc cầu. Nếu đây là một cách khác để tiếp cận điều này. Sử dụng API thông thạo để lập bản đồ như dưới đây. Bạn có thể thay đổi UserProfileToMartialArt thành bất kỳ thứ gì bạn muốn tên bảng. Thay vì tạo ra mô hình MartialArtUserProfile, hãy để EF tạo ra nền tảng trung gian cho bạn. Điều này cũng chỉ định các khóa của bạn sẽ giúp bạn khắc phục lỗi.

modelBuilder.Entity<UserProfile>() 
    .HasMany(b => b.MartialArts) 
    .WithMany(a => a.UserProfiles) 
    .Map(m => m.MapLeftKey("MartialArtId") 
     .MapRightKey("UserProfileId") 
     .ToTable("UserProfileToMartialArt")); 

Trong martialarts Mẫu đặt

public IList<UserProfile> UserProfiles { get; set; } 

Trong UserProfile Mẫu đặt

public IList<MartialArt> MartialArts { get; set; } 
+1

Tôi đã nhận được phản hồi đánh giá, sử dụng .Map thông thạo để xác định mối quan hệ ở trên, không phải là phương pháp hay nhất, vì giải pháp có thể được biên dịch sau khi thay đổi và sẽ không đến khi thời gian chạy hiển thị điều này. Bạn có đề nghị sử dụng Reflection, hoặc một số phương tiện khác (ngoài đỉnh đầu của tôi, gán thuộc tính table entity và ánh xạ tới hằng số?) –

6

Hãy thử làm việc đó như thế này:

[Table("UserProfile")] 
public class UserProfile 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string UserName { get; set; } 

    [InverseProperty("UserProfiles")] 
    public IList<MartialArt> MartialArts { get; set; } 
} 

[Table("MartialArt")] 
public class MartialArt 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Description { get; set; } 

    public string IconPath { get; set; } 

    public string ImagePath { get; set; } 

    [InverseProperty("MartialArts")] 
    public IList<UserProfile> UserProfiles { get; set; } 
} 
+0

Tính năng này hoạt động tốt cho tôi. Mặc dù tôi đang ở trong một tình huống mà tôi quan tâm * chỉ * một thực thể được liên kết với nhau. Có thể sử dụng điều này? Lúc đầu, tôi chỉ có một IList Khác {get; set;} nhưng nó không hoạt động chính xác – Mzn

+0

Bạn đang nói về mối quan hệ 1-1? –

+0

Tôi đang nói về mối quan hệ nhiều người (một chiều) ... bằng một chiều tôi muốn nói trong mã của mình tôi muốn có một tài sản điều hướng. Đây không phải là một vấn đề lớn cả, tôi chỉ tự hỏi làm thế nào, nếu có thể – Mzn

5

Trong EntityFramework 6.1, bạn không cần phải làm bất cứ điều này - chỉ cần thêm bộ sưu tập của hai các loại cho mỗi lớp và mọi thứ rơi vào vị trí.

public class UserProfile { 
    public int Id { get; set; } 
    public string UserName { get; set; } 
    public virtual ICollection<MartialArt> MartialArts { get; set; } 

    public UserProfile() { 
     MartialArts = new List<MartialArt>(); 
    } 
} 

public class MartialArt { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    // *snip* 
    public virtual ICollection<UserProfile> UserProfiles { get; set; } 

    public MartialArt() { 
     UserProfiles = new List<UserProfile>(); 
    } 
} 
+0

Awesome, đã làm việc cho tôi. Đây là cách nó nên được. Đi 6.1 – parliament

+0

Nếu đây là một sự tiến hóa của câu trả lời của Admir ở trên (http://stackoverflow.com/a/15328042/489396) và 'rơi vào vị trí' được dựa trên quy ước, các quy ước nào được yêu cầu giữa bảng bản đồ? –

+1

@GusCrawford - Bảng ánh xạ được giữ hoàn toàn ẩn khỏi mã của bạn, nó sẽ được tạo ra đơn giản bằng cách có hai bộ sưu tập đối tượng đối diện trong mã của bạn. –

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