Reputation: 23
I use Code First EF 5.0 on >Net 4.0 and I has 2 class:
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; }
}
and mapping:
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);
}
}
If I write next code:
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
}
OR:
int breedID = 1; // some value
Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);
if (br != null)
{
_kennel.MainBreedID = breedID;
// but: _kennel.MainBreed != br
}
Why EF doesnt update navigation property? I set ProxyCreationEnabled and AutoDetectChangesEnabled, but this not work.
See another example of sample code (it accurately reflects my real application code):
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);
}
After call to DetectChanges all navigation properties and collection reflect changes (kennel.MainBreedID != null).
Upvotes: 2
Views: 370
Reputation: 6026
Try making all your POCO properties virtual rather than just the navigation properties. This will allow EF to create change tracking proxies rather than lazy loading proxies. I've not tested this, but you may then get the behavior that you expect.
Upvotes: 3
Reputation: 14580
Remove the intialisation of the collections from the constructor
//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>();
Upvotes: 0