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 に答える