简体   繁体   中英

C# EF update related entities

I am trying to update references between 2 entities. Sadly my update methods only work on simple fields, but not on whole entities.

In my DbContext I have the update method:

public void UpdateProject(Project e)
{
    this.projects.Attach(e);
    this.employees.Attach(e.ProjectLeader); //added later
    this.Entry<Project>(e).State = EntityState.Modified;
    this.Entry<Employee>(e.ProjectLeader).State = EntityState.Modified; //added later
    this.SaveChanges();
}

The ones I added later were added because of different suggestions throughout the web.

I have following (simplified) classes:

public class Employee
{
    [DataMember]
    public int? ID { get; set; }

    [DataMember]
    public String Name { get; set; }

    [DataMember]
    public virtual Project LeaderOfProject { get; set; }
}

and

public class Project
{
    [DataMember]
    public int? ID { get; set; }

    [DataMember]
    public String Titel { get; set; }

    [DataMember]
    public Employee ProjectLeader { get; set; }
}

This relationship is defined in my OnModelCreate method like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

    modelBuilder.Entity<Employee>()
                .HasOptional<Project>(e => e.LeaderOfProject)
                .WithOptionalPrincipal(p => p.ProjectLeader)
                .Map(m => m.MapKey("ProjectLeader"));
}

With the update method shown above I am able to update the Titel field, but I can't assign any Employee as new ProjectLeader (no error, but no update as well).

What do I need to change to update/change the related entities?

Any help is really appreciated.


I also tried with

this.Entry(e).CurrentValues.SetValues(e);
this.Entry(e.ProjectLeader).CurrentValues.SetValues(e.ProjectLeader);

but no success.

Method to retrieve objects from EF:

public Project FindProjectById(int id)
{
    Project Result = this.projects
        .Include(x => x.ProjectLeader)
        .Include(x => x.EmployeesWorkingOnProject)
        .Include(x => x.ProjectSteps)
        .SingleOrDefault(x => x.ID == id);
    return Result;
}

I don't believe you can do this by attaching the modified entity to the context vs. loading the original entities, disassociating the reference between them, then associating the new references.

Given a record that had Employee A <-> Project A you change the detached entities so that Employee B <-> Project A.

Project A's Employee might be pointing at B, but according to the context, Employee A's still pointing at Project A. Employee is the principal.

Bidirectional references are almost always a pain. :)

What you'll likely need to do would be something like:

public void UpdateProject(Project e)
{
    var project = this.projects.Find(e.ProjectId);
    project.ProjectLeader.LeaderOfProject = null; // De-associate Employee A's project.
    //Copy values from e to project.
    project.StartDate = e.StartDate; // May be able to use CopyValues against Entity(project)... Would need to test. :)

    var employee = this.employees.Attach(e.ProjectLeader); // Attach employee B to this context.
    project.ProjectLeader = employee; // Associate Employee B to project, and project to employee B.
    employee.LeaderOfProject = project;
    this.SaveChanges();
}

Caveat: I'm not 100% sure this will work, but hopefully it gives you some ideas to narrow down how to re-associate the entities.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM