C # EF обновить связанные объекты - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь обновить ссылки между двумя объектами.К сожалению, мои методы обновления работают только на простых полях, но не на целых объектах.

В моем DbContext у меня есть метод обновления:

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

Те, которые я добавил позже, были добавлены, потому чторазличных предложений по всему Интернету.

У меня есть следующие (упрощенные) классы:

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

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

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

и

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

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

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

Это отношение определено в моем методе OnModelCreate следующим образом:

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"));
}

С помощью метода обновления, показанного выше, я могу обновить поле Titel, но я не могу присвоить Employee как новый ProjectLeader (без ошибок, но и без обновления).

Что мне нужно изменить, чтобы обновить / изменить связанные объекты?

Любая помощь очень ценится.


Я также пытался с

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

, но безуспешно.

Метод извлечения объектов из 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;
}

1 Ответ

0 голосов
/ 15 мая 2018

Я не верю, что вы можете сделать это, прикрепив измененную сущность к контексту вместо загрузки исходных сущностей, разобщив ссылку между ними, а затем связав новые ссылки.

Учитывая запись, в которой был Сотрудник А <-> Проект А Вы изменяете отдельные объекты таким образом, чтобы Сотрудник B <-> Проект A.

Сотрудник проекта A может указывать на B, но в зависимости от контекста сотрудник A все еще указывает на проект A. Сотрудник является основным.

Двунаправленные ссылки - почти всегда боль. :)

То, что вам, вероятно, нужно будет сделать, будет выглядеть примерно так:

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

Предостережение: я не уверен на 100%, что это будет работать, но, надеюсь, это даст вам некоторые идеи, чтобы сузить, как заново связать сущности.

...