2

我在 >Net 4.0 上使用 Code First EF 5.0,我有 2 个类:

public partial class Kennel
{
    public Kennel()
    {
        this.Brands = new List<Brand>();
        this.Dogs = new List<Dog>();
        this.Breeds = new List<Breed>();
        this.Owners = new List<Person>();
        this.Name1 = new KennelName();
        this.Name2 = new KennelName();
    }

    public int ID { get; set; }
    public /*DogClub*/int Type { get; set; }
    public KennelName Name1 { get; set; }
    public KennelName Name2 { get; set; }
    public string CertificateNumber { get; set; }
    public System.DateTime? AssigmentDate { get; set; }
    public string Folder { get; set; }
    public string Comment { get; set; }
    public int StatusID { get; set; }
    public int? FederationID { get; set; }
    public int? MainOwnerID { get; set; }
    public int? MainBreedID { get; set; }

    public virtual ICollection<Brand> Brands { get; set; }
    public virtual ICollection<Dog> Dogs { get; set; }
    public virtual Breed MainBreed { get; set; }
    public virtual Federation Federation { get; set; }
    public virtual Status Status { get; set; }
    public virtual Person MainOwner { get; set; }
    public virtual ICollection<Breed> Breeds { get; set; }
    public virtual ICollection<Person> Owners { get; set; }
}

public partial class Breed
{
    public Breed()
    {
        this.Dogs = new List<Dog>();
        this.ExpertKerungs = new List<ExpertKerung>();
        this.Hallmarks = new List<Hallmark>();
        this.Colors = new List<Color>();
        this.ExpertBreeds = new List<ExpertBreed>();
        this.Kennels = new List<Kennel>();
        this.MainKennels = new List<Kennel>();
    }

    public int ID { get; set; }
    public string FciNumber { get; set; }
    public string Name { get; set; }
    public int BreedGroupID { get; set; }
    public bool IsKerung { get; set; }
    public string NameLat { get; set; }
    public string NativeName { get; set; }
    public int CountryID { get; set; }
    public System.DateTime? StandardDate { get; set; }
    public bool IsCACIB { get; set; }
    public bool IsWork { get; set; }

    public virtual BreedGroup BreedGroup { get; set; }
    public virtual ICollection<Dog> Dogs { get; set; }
    public virtual ICollection<ExpertKerung> ExpertKerungs { get; set; }
    public virtual ICollection<Hallmark> Hallmarks { get; set; }
    public virtual ICollection<Color> Colors { get; set; }
    public virtual Country Country { get; set; }
    public virtual ICollection<ExpertBreed> ExpertBreeds { get; set; }
    public virtual ICollection<Kennel> Kennels { get; set; }
    public virtual ICollection<Kennel> MainKennels { get; set; }
}

和映射:

public class KennelMap : EntityTypeConfiguration<Kennel>
{
    public KennelMap()
    {
        // Primary Key
        this.HasKey(t => t.ID);

        // Properties
        //this.Property(t => t.Name1.Name)
        //    .IsRequired();

        //this.Property(t => t.Name1.IntlName)
        //    .IsRequired();

        //this.Property(t => t.Name2.Name)
        //    .IsRequired();

        //this.Property(t => t.Name2.IntlName)
        //    .IsRequired();

        // Table & Column Mappings
        this.ToTable("Kennels");
        this.Property(t => t.ID).HasColumnName("ID");
        this.Property(t => t.Type).HasColumnName("Type");
        this.Property(t => t.Name1.Name).HasColumnName("Name1_Name");
        this.Property(t => t.Name1.IntlName).HasColumnName("Name1_IntlName");
        this.Property(t => t.Name1.Type).HasColumnName("Name1_Type");
        this.Property(t => t.Name1.Approved).HasColumnName("Name1_Approved");
        this.Property(t => t.Name2.Name).HasColumnName("Name2_Name");
        this.Property(t => t.Name2.IntlName).HasColumnName("Name2_IntlName");
        this.Property(t => t.Name2.Type).HasColumnName("Name2_Type");
        this.Property(t => t.Name2.Approved).HasColumnName("Name2_Approved");
        this.Property(t => t.CertificateNumber).HasColumnName("CertificateNumber");
        this.Property(t => t.AssigmentDate).HasColumnName("AssigmentDate");
        this.Property(t => t.Folder).HasColumnName("Folder");
        this.Property(t => t.Comment).HasColumnName("Comment");
        this.Property(t => t.StatusID).HasColumnName("StatusID");
        this.Property(t => t.FederationID).HasColumnName("FederationID");
        this.Property(t => t.MainOwnerID).HasColumnName("MainOwnerID");

        // Relationships
        this.HasMany(t => t.Owners)
                .WithMany(t => t.Kennels)
                .Map(m =>
                        {
                            m.ToTable("OwnerKennel");
                            m.MapLeftKey("Kennels_ID");
                            m.MapRightKey("Owners_ID");
                        });

        this.HasOptional(t => t.MainBreed)
                .WithMany(t => t.MainKennels)
                .HasForeignKey(d => d.MainBreedID);
        this.HasOptional(t => t.Federation)
                .WithMany(t => t.Kennels)
                .HasForeignKey(d => d.FederationID);
        this.HasRequired(t => t.Status)
                .WithMany(t => t.Kennels)
                .HasForeignKey(d => d.StatusID);
        this.HasOptional(t => t.MainOwner)
                .WithMany(t => t.MainKennels)
                .HasForeignKey(d => d.MainOwnerID)
                .WillCascadeOnDelete(false);

    }
}

如果我写下一个代码:

  int breedID = 1; // some value  
  Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);  
  if (br != null)  
  {  
    _kennel.MainBreed = br;  
    // but: _kennel.MainBreedID != br.ID  
  }  

或者:

  int breedID = 1; // some value  
  Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);  
  if (br != null)  
  {  
    _kennel.MainBreedID = breedID;  
    // but: _kennel.MainBreed != br  
  }  

为什么 EF 不更新导航属性?我设置了 ProxyCreationEnabled 和 AutoDetectChangesEnabled,但这不起作用。

查看示例代码的另一个示例(它准确地反映了我的真实应用程序代码):

Kennel kennel = ctx.Kennels.Add(ctx.Kennels.Create());
kennel.Name1.Name = "Test Kennel";
List<Breed> breeds = ctx.Breeds.Include(b => b.BreedGroup).OrderBy(t => t.BreedGroupID).Where(t => t.ID == 755 || t.ID == 772).ToList();
foreach (var b in breeds)
  kennel.Breeds.Add(b);
if (breeds.Count > 0)
{
  kennel.MainBreed = breeds[0];
  foreach (var k in kennel.MainBreed.MainKennels)
    System.Diagnostics.Debug.WriteLine("MainKennel: " + k.Name1.Name);
  ctx.ChangeTracker.DetectChanges();
  //System.Diagnostics.Debug.WriteLine("MainBreed: " + kennel.MainBreed);
  System.Diagnostics.Debug.WriteLine("MainBreedID: " + kennel.MainBreedID);
}

调用 DetectChanges 后,所有导航属性和集合都会反映更改(kennel.MainBreedID != null)。

4

2 回答 2

3

尝试使您的所有 POCO 属性虚拟化,而不仅仅是导航属性。这将允许 EF 创建更改跟踪代理而不是延迟加载代理。 我没有对此进行测试,但是您可能会得到您期望的行为。

于 2013-02-12T13:45:14.813 回答
0

从构造函数中删除集合的初始化

//this.Dogs = new List<Dog>();
//this.ExpertKerungs = new List<ExpertKerung>();
//this.Hallmarks = new List<Hallmark>();
//this.Colors = new List<Color>();
//this.ExpertBreeds = new List<ExpertBreed>();
//this.Kennels = new List<Kennel>();
//this.MainKennels = new List<Kennel>();
于 2013-02-12T12:25:21.843 回答