1

I created my database and started developing a web application in c# with EF5 and the DB First approach. I can modify my entities on their own data fields but don´t get it to work when it comes to updating relationships. A simple relationship example is Project <- ProjectCategoryIntersection -> Category

Model:

 public class Project
 {
  public TProject project { get; private set; }
  public List<string> Categories { get; set; }   
 }

 public partial class TProject  //generated table object 
 { 
   public virtual ICollection<TProjectCategoryIntersection> TProjectCategoryIntersection { get; set; }
 }

public partial class TProjectCategoryIntersection
{
    public int Id { get; set; }
    public int ProjectId { get; set; }
    public int ProjectCategoryId { get; set; }

    public virtual TProject T_Project { get; set; }
    public virtual TCategory T_ProjectCategory { get; set; }
}

Save:

 public void SaveProject(Project project)
 {
 var context = new ProjectManagementEntities();

 TProject projectToUpdate = new TProject();
 projectToUpdate.Id = project.Id;

 foreach (var category in project.Categories)
 {
    var cat = (from c in context.TProjectCategory
                where c.Name == category
                select c).FirstOrDefault();
                var inters = new TProjectCategoryIntersection() { ProjectCategoryId = cat.Id, ProjectId = project.project.Id, TProject = project.project, TProjectCategory = cat };
                projectToUpdate.TProjectCategoryIntersection.Add(inters);
 }

 var entry = context.Entry(projectToUpdate).State = EntityState.Modified; //throws exceptions
 context.SaveChanges();
}

exception:

Conflicting changes to the role 'TProject' of the relationship 'ProjectManagementModel.FK_TProjectCategoryIntersection_TProject' have been detected.

I also receive a multiple instances ChangeTracker exception when i try to add the categories directly to the project object:

project.project.TProjectCategoryIntersection.Add(inters);

Should i remove the generated table object from my model?

public class Project
 {
  public TProject project { get; private set; } //remove this?
  public List<string> Categories { get; set; }   
 }

Solution

I ended up removing the generated table object public TProject project { get; private set; } and changed my code to:

 public void SaveProject(Project project)
 {

            var context = new ProjectManagementEntities();

            var projectToUpdate = context.T_Project.Find(project.Id);
            foreach (var item in projectToUpdate.T_ProjectCategoryIntersection.ToList())
            {
                var oldCat = context.T_ProjectCategoryIntersection.Find(item.Id);
                context.T_ProjectCategoryIntersection.Remove(oldCat);
            }

            foreach (var category in project.Categories)
            {
                var cat = (from c in context.T_ProjectCategory
                           where c.Name == category
                           select c).FirstOrDefault();
                var inters = new T_ProjectCategoryIntersection() { ProjectCategoryId = cat.Id, ProjectId = project.Id };

                context.T_ProjectCategoryIntersection.Add(inters);
            }
            //more code...
            context.Entry(projectToUpdate).State = EntityState.Modified;
            context.SaveChanges();
  }
Frank
  • 1,113
  • 3
  • 14
  • 27

1 Answers1

0

Apperantly this happens when you use reference to an object and also an Integer for the ID within the same object and change both of them. When this happens EF can not know which one is the correct reference

Try setting only Ids and set null for references like

var inters = new TProjectCategoryIntersection() { ProjectCategoryId = cat.Id, 
ProjectId = project.project.Id};
caner
  • 721
  • 5
  • 21