2013-04-16 2 views
0

В следующем коде я сначала использую код EF для настройки моей модели базы данных.Составной ключ EF 5 с большим отношением к другому объекту

Сущность CaseCommunication имеет составной ключ, включающий столбец идентификатора. Если я позволяю 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.

Смежные вопросы