Сохранение зависимой записи без создания дубликата основной записи - PullRequest
0 голосов
/ 29 ноября 2018

С помощью EF Core я создаю основную запись, но при добавлении и сохранении зависимой записи она будет пытаться создать новый дубликат участника.

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

Модели сущностей создаются таким образом.

public class Company
{
    public string ID { get; set; }
    public string Name { get; set; }
}

public class Employee
{
    public string ID { get; set; }
    public string Title { get; set; }
    public string Name { get; set; }

    public string CompanyID { get; set; }

    [ForeignKey("CompanyID")]
    public Company Company { get; set; }
}

A DbContext создан для того, чтобы представлять их как DbSet.

public class OrganizationContext : DbContext
{
    public DbSet<Company> Companies { get; set; }
    public DbSet<Employee> Employees { get; set; }

    // ...
}

При передаче полного объекта из представления для добавления сотрудника в компанию с помощью OrganizationContext он также попытается создать новую запись о компании.

var comp = new Company()
{
    comp.ID = "1",
    comp.Name = "The Daily Planet"
};

var emp = new Employee()
{
    emp.ID = "00123",
    emp.Title = "Supervisor",
    emp.Name = "Clark Kent",
    emp.CompanyID = "1",
    emp.Company = comp
};

_context.Employees.Add(emp);
_context.SaveChanges();

Если я установлю атрибут Company как неизменный, он все равно попытается вставить новую компанию.

_context.Employees.Add(emp);
_context.Entry(emp.Company).State = EntityState.Unchanged;
_context.SaveChanges();

Если я установлю emp.Company на null, он не будет пытаться добавитьновая компания

emp.Company = null;
_context.Employees.Add(emp);

Существует ли правильный способ настройки связей модели или структуры для добавления сотрудника в компанию без необходимости вручную изменять граф объектов перед сохранением?

1 Ответ

0 голосов
/ 29 ноября 2018

Это потому, что вы используете Add метод, который по определению каскадно выполняет операцию Add для каждой достижимой сущности:

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

Если вы использовали сущности с автоматически сгенерированными PK, правильный способ - использовать метод Update, как описано в Сочетание новых и существующих сущностей :

С автоматически сгенерированными ключами Update можно снова использовать как для вставок, так и для обновлений, даже если график содержит комбинацию сущностей, которые требуютвставка и те, которые требуют обновления

с последующим примером и затем:

Обновление помечает любую сущность на графике, в блоге или записи для вставки, если это не такустановите значение ключа, в то время как все остальные объекты помечены для обновления.

К сожалению, ваш случай отличается.Не существует универсального готового метода для добавления или обновления.Одно из решений состоит в том, чтобы не устанавливать свойство навигации, а только свойство FK (которое, к счастью, у вас есть):

//var comp = new Company()
//{
//    comp.ID = "1",
//    comp.Name = "The Daily Planet"
//};

var emp = new Employee()
{
    emp.ID = "00123",
    emp.Title = "Supervisor",
    emp.Name = "Clark Kent",
    emp.CompanyID = "1",
    //emp.Company = comp
};

_context.Employees.Add(emp);
_context.SaveChanges();

Другой способ, который обойдется вам в двустороннюю поездку, состоит в том, чтобы разрешить связанный существующий объект из контекста.:

var comp = _context.Companies.Find("1");

var emp = new Employee()
{
    emp.ID = "00123",
    emp.Title = "Supervisor",
    emp.Name = "Clark Kent",
    //emp.CompanyID = "1", // Not needed, but won't hurt if you include it
    emp.Company = comp
};

_context.Employees.Add(emp);
_context.SaveChanges();

Последний вариант - использовать TrackGraph и принимать индивидуальные решения для каждой сущности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...