2013-04-16 69 views
0

在下面的代碼中,我首先使用EF代碼來設置我的數據庫模型。帶有與其他實體有很多關係的EF 5複合鍵

CaseCommunication實體具有包含Id列的組合鍵。如果我讓EF做的工作,它試圖儘管許多()規範使用此列的FK其他實體:

HasRequired(x => x.Case).WithMany(x => x.Communications); 
HasOptional(x => x.FirstReadBy).WithMany(); 

爲了得到正確的模型,我必須明確地設置了FK(請閱讀代碼中的註釋)。

HasRequired(x => x.Case).WithMany(x => x.Communications).Map(x => x.MapKey("Case_Id")); 
HasOptional(x => x.FirstReadBy).WithMany().Map(x => x.MapKey("FirstReadBy_Id")); 

如果我不使用複合鍵,那麼所有工作正常,不使用Map()。

我的問題是:什麼是EF的邏輯?或者換個說法,我錯過了什麼?

using System; 
using System.Linq; 
using System.Data.Entity; 
using System.Collections.Generic; 
using System.Data.Entity.ModelConfiguration; 
using System.Data.Objects.SqlClient; 
using System.ComponentModel.DataAnnotations.Schema; 

namespace testef { 
    //Model 
    public partial class Case { 
     public Case() {     
      Communications = new List<CaseCommunication>(); 
     } 
     public Int32 Id { get; set; } 

     public virtual ICollection<CaseCommunication> Communications { get; set; } 
    } 

    public class CaseCommunication { 

     public String CComType { get; set; } 
     public Int32 Id { get; set; } 

     public virtual Case Case { get; set; } 

     public virtual User FirstReadBy { get; set; } 
    } 

    public class User { 
     public Int32 Id { get; set; } 
    } 

    //Configuration for CObj 
    public class UserEFCFConfiguration : EntityTypeConfiguration<User> { 
     public UserEFCFConfiguration() 
      : base() { 
      ToTable("Users", "dbo"); 
      HasKey(x => x.Id); 
      Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     } 
    } 

    public class CaseEFCFConfiguration : EntityTypeConfiguration<Case> { 
     public CaseEFCFConfiguration() 
      : base() { 
      ToTable("Cases", "dbo"); 
      HasKey(x => x.Id); 
      Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     } 
    } 

    public class CaseCommunicationEFCFConfiguration : EntityTypeConfiguration<CaseCommunication> { 
     public CaseCommunicationEFCFConfiguration() 
      : base() { 
      ToTable("VCaseCommunications", "dbo"); 
      Property(x => x.CComType).HasColumnType("char").HasMaxLength(2); 

      HasKey(x => new { x.CComType, x.Id }); 

      // OK 
      HasRequired(x => x.Case).WithMany(x => x.Communications).Map(x => x.MapKey("Case_Id")); 
      HasOptional(x => x.FirstReadBy).WithMany().Map(x => x.MapKey("FirstReadBy_Id")); 

      // KO 
      //HasRequired(x => x.Case).WithMany(x => x.Communications); 
      //HasOptional(x => x.FirstReadBy).WithMany() 
      //EF tries to use the x.Id as FK for both Case and FirstReadBy 
      //For FirstReadBy this leads to a Model error as x.Id is not nullable 
      //But in each case I can't understand how EF expect to give the many relation by using a part of the PK as FK 

      // OK 
      //HasKey(x => x.Id); 
      //HasRequired(x => x.Case).WithMany(x => x.Communications); 
      //HasOptional(x => x.FirstReadBy).WithMany() 
     } 
    } 

    public class TestEFContext : DbContext { 
     public IDbSet<Case> Cases { get; set; } 

     public TestEFContext(String cs) 
      : base(cs) { 
      Database.SetInitializer<TestEFContext>(new DropCreateDatabaseAlways<TestEFContext>()); 
     } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
      base.OnModelCreating(modelBuilder); 

      modelBuilder.Configurations.Add(new UserEFCFConfiguration()); 
      modelBuilder.Configurations.Add(new CaseEFCFConfiguration()); 
      modelBuilder.Configurations.Add(new CaseCommunicationEFCFConfiguration()); 
     } 
    } 

    class Program { 
     static void Main(String[] args) { 
      String cs = @"Data Source=ALIASTVALK;Initial Catalog=TestEF;Integrated Security=True; MultipleActiveResultSets=True";     

      using (TestEFContext c = new TestEFContext(cs)) { 
       Console.WriteLine(c.Cases.Count()); 
      }                 
     } 
    } 
} 

回答

0

事實上,這似乎是EF的默認行爲:如果鏈接的實體鍵的部分具有相同的名稱作爲引用的實體PK,那麼這所以命名的屬性被用作FK。

相關問題