Entity Framework 6 several one-to-mmay - entity-framework

Onother problem with Entity Framework 6. I don't know why, but I have some trouble to get back my object frome the database when I queue 2 one-to-many relationships.
My plain objects
public class Plan
{
public int id { get; set; }
public int largeur { get; set; }
public int longueur { get; set; }
public string nom { get; set; }
public virtual List<Etage> listEtages { get; set; }
public Plan() { }
}
public class Etage
{
public int id { get; set; }
public virtual List<PositionModule> listPositionModule { get; set; }
public virtual Plan plan { get; set; }
public Etage() { }
}
public class PositionModule
{
public int id { get; set; }
public int x1 { get; set; }
public int x2 { get; set; }
public int y1 { get; set; }
public int y2 { get; set; }
public string lineId { get; set; }
public virtual Module module { get; set; }
public virtual Etage etage { get; set; }
public PositionModule() { }
}
public class Module
{
public int id { get; set; }
public string libe { get; set; }
public string coupePrincipe { get; set; }
public virtual TModule typeModule { get; set; }
public decimal prix { get; set; }
public Module()
{
}
}
Ef6 fluent mapping
public class PlanConfiguration : EntityTypeConfiguration<Plan>
{
public PlanConfiguration()
{
ToTable("Plan");
HasKey<int>(a => a.id);
Property<int>(a => a.largeur).IsRequired();
Property<int>(a => a.longueur).IsRequired();
Property(a => a.nom).HasColumnType("varchar").HasMaxLength(50);
}
}
public class EtageConfiguration : EntityTypeConfiguration<Etage>
{
public EtageConfiguration()
{
ToTable("Etage");
HasKey<int>(a => a.id);
HasRequired<Plan>(x => x.plan).WithMany(x => x.listEtages);
}
}
public class PositionModuleConfiguration : EntityTypeConfiguration<PositionModule>
{
public PositionModuleConfiguration()
{
ToTable("PositionModule");
HasKey<int>(a => a.id);
HasRequired<Module>(a => a.module);
HasRequired<Etage>(x => x.etage).WithMany(x => x.listPositionModule);
Property<int>(x => x.x1);
Property<int>(x => x.x2);
Property<int>(x => x.y1);
Property<int>(x => x.y2);
Property(a => a.lineId).HasColumnType("varchar").HasMaxLength(30);
}
}
public class ModuleConfiguration : EntityTypeConfiguration<Module>
{
public ModuleConfiguration()
{
ToTable("Module");
HasKey<int>(a => a.id);
HasOptional<TModule>(a => a.typeModule);
Property(a => a.libe).HasColumnType("varchar").HasMaxLength(150);
Property(a => a.coupePrincipe).HasColumnType("varchar");
}
}
At the moment I'm able to store a Plan which has a list of Etage with many PositionModule.
But when I want to get back my all plan with a get by id, the listEtages is empty.
By checking on the database, all foreign keys are good and I use the one-to-many with two other (simplier) objects and it works fine...
It's my first project with EF6 so if you have any tips to share, it will be a pleasure.
Thanks
Update
My DTOs
public class PlanDTO
{
public int id { get; set; }
public int largeur { get; set; }
public int longueur { get; set; }
public string nom { get; set; }
public List<EtageDTO> lesEtages { get; set; }
public PlanDTO()
{
lesEtages = new List<EtageDTO>();
}
}
public class EtageDTO
{
public int id { get; set; }
public List<PositionModuleDTO> lesModules { get; set; }
public PlanDTO plan { get; set; }
public EtageDTO()
{
lesModules = new List<PositionModuleDTO>();
plan = new PlanDTO();
}
}
public class PositionModuleDTO
{
public int id { get; set; }
public int x1 { get; set; }
public int x2 { get; set; }
public int y1 { get; set; }
public int y2 { get; set; }
public string lineId { get; set; }
public ModuleDTO module { get; set; }
public EtageDTO etage { get; set; }
public PositionModuleDTO()
{
module = new ModuleDTO();
}
}
public class ModuleDTO
{
public string libe { get; set; }
public int id { get; set; }
public string coupePrincipe { get; set; }
public TModule typeModule { get; set; }
}
How I mapp my DTOs and Plain objects (with automapper)
--- ViewModelToDomain ---
CreateMap<PlanDTO, Plan>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.largeur, map => map.MapFrom(vm => vm.largeur))
.ForMember(g => g.longueur, map => map.MapFrom(vm => vm.longueur))
.ForMember(g => g.nom, map => map.MapFrom(vm => vm.nom))
.ForMember(g => g.listEtages, map => map.MapFrom(vm => vm.lesEtages));
CreateMap<EtageDTO, Etage>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.listPositionModule, map => map.MapFrom(vm => vm.lesModules))
.ForMember(g => g.plan, map => map.MapFrom(vm => vm.plan));
CreateMap<PositionModuleDTO, PositionModule>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.x1, map => map.MapFrom(vm => vm.x1))
.ForMember(g => g.x2, map => map.MapFrom(vm => vm.x2))
.ForMember(g => g.y1, map => map.MapFrom(vm => vm.y1))
.ForMember(g => g.y2, map => map.MapFrom(vm => vm.y2))
.ForMember(g => g.module, map => map.MapFrom(vm => vm.module))
.ForMember(g => g.etage, map => map.MapFrom(vm => vm.etage));
CreateMap<ModuleDTO, Module>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.libe, map => map.MapFrom(vm => vm.libe))
.ForMember(g => g.typeModule, map => map.MapFrom(vm => vm.typeModule))
.ForMember(g => g.coupePrincipe, map => map.MapFrom(vm => vm.coupePrincipe));
--- DomainToViewModel ---
CreateMap<Plan, PlanDTO>();
CreateMap<Etage, EtageDTO>();
CreateMap<PositionModule, PositionModuleDTO>();
CreateMap<Module, ModuleDTO>();
The controller where I create and try to get back my plan
[HttpPost]
public ActionResult SavePlan(PlanDTO plan)
{
if (plan != null)
{
Plan planP = new Plan();
plan.nom = "test";
planP=Mapper.Map<PlanDTO, Plan>(plan);
try
{
_planService.Create(planP);//The plan is create
/*
refers to
public virtual void Insert(T entity)
{
dbSet.Add(entity);
}
*/
_planService.Save();
}
catch(Exception e)
{
throw (e);
}
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
}
[HttpPost]
public JsonResult GetPlan(int id)
{
try
{
List<ModuleDTO> lesModules = Mapper.Map<List<Module>, List<ModuleDTO>>(_moduleService.DonneTous().ToList());
PlanDTO plan = Mapper.Map<Plan, PlanDTO>(_planService.Get(id));//I have id, largeur, longueure and nom but listEtages is empty (all data are in database)
/*
refers to
public virtual T GetById(int id)
{
return dbSet.Find(id);
}
*/
return Json(plan);
}
catch(Exception e)
{
return Json("An Error Has occoured");
}
}

Related

Entity Framework Core 3 : Pulling data from multiple sources using join

I basically have three tables that I need to query information to get PersonNotes. I am using Entity Framwork Core 3.
Person Table
PersonNote Table
PersonNoteAttachment Table
One person can have many personnotes and one personnote can contain many PersonNoteAttachment.
I need Person table to get the FirstName and LastName which is mapped to the AuthorName in the PersonNote User data model. You can see the mapping section which shows the mapping.
DataModels
namespace Genistar.Organisation.Models.DataModels
{
[Table(nameof(PersonNote), Schema = "common")]
public class PersonNote
{
public int Id { get; set; }
public int PersonId { get; set; }
[ForeignKey("PersonId")]
public Person Person { get; set; }
public string Note { get; set; }
public int AuthorId { get; set; }
[ForeignKey("AuthorId")]
public Person Author { get; set; }
public string CreatedBy { get; set; }
public DateTime Created { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordStartDateTime { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordEndDateTime { get; set; }
}
}
namespace Genistar.Organisation.Models.DataModels
{
[Table(nameof(PersonNoteAttachment), Schema = "common")]
public class PersonNoteAttachment
{
public int Id { get; set; }
public int PersonNoteId { get; set; }
[ForeignKey("PersonNoteId")]
public PersonNote PersonNote { get; set; }
public string Alias { get; set; }
public string FileName { get; set; }
public string MimeType { get; set; }
public int Deleted { get; set; }
public string CreatedBy { get; set; }
public DateTime Created { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordStartDateTime { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordEndDateTime { get; set; }
}
}
User Model - This is the model that I am returning to the client application
namespace Genistar.Organisation.Models.User
{
[Table(nameof(PersonNote), Schema = "common")]
public class PersonNote
{
public int Id { get; set; }
public int PersonId { get; set; }
public string Note { get; set; }
public int AuthorId { get; set; }
public string AuthorName { get; set; }
public string CreatedBy { get; set; }
public DateTime Created { get; set; }
}
}
Mapping
CreateMap<Genistar.Organisation.Models.DataModels.PersonNote, Genistar.Organisation.Models.User.PersonNote>()
.ForMember(t => t.Id, opt => opt.MapFrom(s => s.Id))
.ForMember(t => t.PersonId, opt => opt.MapFrom(s => s.PersonId))
.ForMember(t => t.AuthorName, opt => opt.MapFrom(s => s.Author.FirstName + " " + s.Author.LastName))
.ForMember(t => t.Note, opt => opt.MapFrom(s => s.Note))
.ForMember(t => t.AuthorId, opt => opt.MapFrom(s => s.AuthorId))
.ForMember(t => t.CreatedBy, opt => opt.MapFrom(s => s.CreatedBy))
.ForMember(t => t.Created, opt => opt.MapFrom(s => s.Created));
The following query works but is only pulling data from Person and PersonNote table. I am looking at getting the PersonNoteAttachment as well. How do I do that ? I would basically need FileName & MimeType
field populated in User.PersonNote model. If you see above I have created a PersonNoteAttachment data model
Repository
public IQueryable<PersonNote> GetPersonNotes(int personId)
{
var personNotes = _context.PersonNotes.Include(x => x.Person).Include(x=> x.Author).Where(p => p.PersonId == personId);
return personNotes;
}
API :
[FunctionName(nameof(GetPersonNote))]
[UsedImplicitly]
public Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "person-note/{id}")] HttpRequest req,
int id) => _helper.HandleAsync(async () =>
{
//await _helper.ValidateRequestAsync(req, SecurityPolicies.ViewNotes);
var personNotes = await _organisationRepository.GetPersonNotes(id).ProjectTo<PersonNote>(_mapper.ConfigurationProvider).ToListAsync();
return new OkObjectResult(personNotes);
});
My approach was to do it the following way in the repository but I need to return the PersonNote datamodel in the repository. I cannot add those additional fields in the model because it say invalid columns.How do I approach this ?
var personNotes = _context.PersonNotes
.Include(x => x.Person)
.Include(x => x.Author)
.Where(p => p.PersonId == personId)
.Join(_context.PersonNotesAttachments, c => c.Id, cm => cm.PersonNoteId, (c, cm) => new
{
cm.PersonNote.Id,
cm.PersonNote.PersonId,
cm.PersonNote.Person,
cm.PersonNote.Note,
cm.FileName,
cm.MimeType,
cm.Alias,
cm.PersonNote.AuthorId,
cm.PersonNote.CreatedBy,
cm.PersonNote.Created
});
I have resolved the issue
I just had to add the following line in PersonNote datamodel
public PersonNoteAttachment PersonNoteAttachment { get; set; }
Added the new fields to the PersonNote usermodel and did the following mapping
.ForMember(t => t.FileName, opt => opt.MapFrom(s => s.PersonNoteAttachment.FileName))
.ForMember(t => t.MimeType, opt => opt.MapFrom(s => s.PersonNoteAttachment.MimeType))
.ForMember(t => t.Alias, opt => opt.MapFrom(s => s.PersonNoteAttachment.Alias))

The Entity create an additional table for many to-many relationships

Today I got a question about how to create a many to many mapping using Entity Framework Code First fluent api.
The problem is that the entity create an additional table beyond that was set for me.
public class Person
{
public Person()
{
courses = new HashSet<Course>();
}
public int PersonID { get; set; }
public String Name { get; set; }
public ICollection<Course> courses { get; set; }
}
public class Course
{
public Course()
{
people = new HashSet<Person>();
}
public int CourseID { get; set; }
public String Name { get; set; }
public ICollection<Person> people { get; set; }
}
public class PersonCourse
{
public int fk_CourseID { get; set; }
public virtual Course course { get; set; }
public int fk_PersonID { get; set; }
public virtual Person person { get; set; }
public String AnotherInformation { get; set; }
}
public class PersonDataConfiguration : EntityTypeConfiguration<Person>
{
public PersonDataConfiguration()
{
ToTable("Person");
Property(c => c.Name).IsRequired();
this.HasMany(c => c.courses).WithMany(t => t.people).Map(m => { m.MapLeftKey("CourseID"); m.MapRightKey("PersonID"); });
}
}
public class CourseDataConfiguration : EntityTypeConfiguration<Course>
{
public CourseDataConfiguration()
{
ToTable("Course");
Property(c => c.Name).IsRequired();
this.HasMany(c => c.people).WithMany(t => t.courses).Map(m => { m.MapLeftKey("PersonID"); m.MapRightKey("CourseID"); });
}
}
public class PersonCourseDataConfiguration : EntityTypeConfiguration<PersonCourse>
{
public PersonCourseDataConfiguration()
{
ToTable("PersonCourseX");
HasKey(c => new { c.fk_CourseID, c.fk_PersonID });
Property(c => c.AnotherInformation).IsRequired();
this.HasRequired(c => c.person).WithMany().HasForeignKey(t => t.fk_PersonID);
this.HasRequired(c => c.course).WithMany().HasForeignKey(t => t.fk_CourseID);
}
}
public class ProgramTesteContext : DbContext
{
public ProgramTesteContext()
: base("MyConnectionString")
{
}
public DbSet<Person> Person { get; set; }
public DbSet<Course> Course { get; set; }
public DbSet<PersonCourse> PersonCourse { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Properties<String>()
.Configure(p => p.HasColumnType("varchar"));
modelBuilder.Properties<String>()
.Configure(p => p.HasMaxLength(100));
modelBuilder.Configurations.Add(new PersonDataConfiguration());
modelBuilder.Configurations.Add(new CourseDataConfiguration());
modelBuilder.Configurations.Add(new PersonCourseDataConfiguration());
}
}
The entity set up two tables for mapping:
PersonCourseX created by me and another CoursePerson table containing only foreign keys without anotherinformation field.
How to make this second table is not created?
Change PersonCourseDataConfiguration as follows:
public class PersonCourseDataConfiguration : EntityTypeConfiguration<PersonCourse>
{
public PersonCourseDataConfiguration()
{
ToTable("PersonCourseX");
HasKey(c => new { c.fk_CourseID, c.fk_PersonID });
Property(c => c.AnotherInformation).IsRequired();
this.HasRequired(c => c.person).WithMany(c => c.courses).HasForeignKey(t => t.fk_PersonID);
this.HasRequired(c => c.course).WithMany(c => c.people).HasForeignKey(t => t.fk_CourseID);
}
}
Remove the commented lines:
public class PersonDataConfiguration : EntityTypeConfiguration<Person>
{
public PersonDataConfiguration()
{
ToTable("Person");
Property(c => c.Name).IsRequired();
//this.HasMany(c => c.courses).WithMany(t => t.people).Map(m => { m.MapLeftKey("CourseID"); m.MapRightKey("PersonID"); });
}
}
public class CourseDataConfiguration : EntityTypeConfiguration<Course>
{
public CourseDataConfiguration()
{
ToTable("Course");
Property(c => c.Name).IsRequired();
//this.HasMany(c => c.people).WithMany(t => t.courses).Map(m => { m.MapLeftKey("PersonID"); m.MapRightKey("CourseID"); });
}
}
Change Person and Course as follows:
public class Person
{
//.. other properties
public ICollection<PersonCourse> courses { get; set; }
}
public class Course
{
//.. other properties
public ICollection<PersonCourse> people { get; set; }
}

EntityType 'FollowerMenuItemMerchant' has no key defined. Define the key for this EntityType

Other people have asked this question and I checked to see if I was making the same errors, and it appears I am not, from what I can tell.
Here is my FollowerMenuItemMerchant class.
public class FollowerMenuItemMerchant
{
[key, Column(Order = 0)]
public int FollowerID { get; set; }
[key, Column(Order = 1)]
public int MenuItemID { get; set; }
[key, Column(Order = 2)]
public int MerchantID { get; set; }
public virtual Follower Follower { get; set; }
public virtual MenuItem MenuItem { get; set; }
public virtual Merchant Merchant { get; set; }
}
And here is the Context class:
public class FlavorPingContext : IdentityDbContext<ApplicationUser>
{
public FlavorPingContext() : base("name=FlavorPingContext")
{
}
public System.Data.Entity.DbSet<FlavorPing.Models.Merchant> Merchants { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.MenuItem> MenuItems { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.MerchantDetails> MerchantDetails { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.Follower> Followers { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.FollowerMenuItemMerchant> FollowerMenuItemMerchants { get; set; }
protected override void OnModelCreating(DbModelBuilder builder) {
// Primary keys
builder.Entity<Follower>().HasKey(q => q.FollowerID);
builder.Entity<MenuItem>().HasKey(q => q.MenuItemID);
builder.Entity<Merchant>().HasKey(q => q.MerchantID);
builder.Entity<FollowerMenuItemMerchant>().HasKey(q =>
new {
q.FollowerID, q.MenuItemID, q.MerchantID
});
// Relationships
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.Follower)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.FollowerID);
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.MenuItem)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.MenuItemID);
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.Merchant)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.MerchantID);
}
}
Can you see where there may be an error?
Yikes, I found it! I used lower case "key", and not uppercase "Key"! Doh!

Entity Framework Many To Many returns null

I have Many To Many relationship defined and when I try to query for the records that should be in the map I get null.
public class Record
{
public int RecordId { get; set; }
public DateTime DateRecordCreated { get; set; }
public ICollection<Street> Streets { get; set; }
public ICollection<Street> CrossStreets { get; set; }
}
public class RecordMap : EntityTypeConfiguration<Record>
{
public RecordMap()
{
// Primary Key
this.HasKey(t => t.RecordId);
this.HasMany(r => r.Streets)
.WithMany(c => c.Records)
.Map(sl =>
{
sl.ToTable("StreetRecordMap", "dbo");
sl.MapLeftKey("RecordId");
sl.MapRightKey("StreetId");
});
this.HasMany(r => r.CrossStreets)
.WithMany(c => c.AnotherRecord)
.Map(sl =>
{
sl.ToTable("AnotherStreetRecordMap", "dbo");
sl.MapLeftKey("RecordId");
sl.MapRightKey("StreetId");
});
this.Property(t => t.DateRecordCreated).IsRequired();
}
}
public class House : Record
{
public string HouseNumber { get; set; }
public string StreeName { get; set; }
public int ZipCode { get; set; }
}
public class Street
{
public int StreetId { get; set; }
public string StreetName { get; set; }
public ICollection<Record> Records { get; set; }
public ICollection<Record> AnotherRecord { get; set; }
}
Now when I run the following query below I get houses.CrossStreets as null, I tried adding enabling lazy loading and had the same out come.
public static void GetRecords()
{
using (var context = new SandboxContext())
{
var entities = context.Houses.Include(r => r.CrossStreets);
var houses = entities.ToList();
}
}

Why EF doesnt update navigation property

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