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());
}
}
}
}