C# WebAPI Cross обновляет данные внутреннего объединения несколькими таблицами - PullRequest
2 голосов
/ 04 марта 2020

Как и в предыдущем вопросе от здесь

Я хочу обновить эти данные как:

employeeTable: FirstName, LastName departmentTable: departmentName workingshift: duration

Однако сейчас я пытаюсь чтобы изменить мой department_id, выходит сообщение об ошибке:

Свойство Department_id является частью ключевой информации объекта и не может быть изменено.

Вот мой запрос на объединение данных:

var result = (from e in DSE.employees
             join d in DSE.departments on e.department_id equals d.department_id
             join ws in DSE.workingshifts on e.shift_id equals ws.shift_id

Во-вторых, вот мое кодирование для попытки изменить department_id

        var result = (from e in DSE.employees
                      join d in DSE.departments on e.department_id equals d.department_id
                      join ws in DSE.workingshifts on e.shift_id equals ws.shift_id
                      where d.department_id == 1
                      select d).FirstOrDefault();

        if (result != null)
        {
            result.department_id = 2;
            DSE.SaveChanges();
        }

Требование:

  • My ServicesEntities is DSE
  • Я использую Entities Framework
  • My department_id является объединенным объект, то же самое относится к моему shift_id
  • Мой `отдел_идентификатор 'не является идентификатором автоматического увеличения

Атрибуты базы данных:

Employee Table has employee_id, FirstName, LastName, Gender, Salary

Department Table has department_id, department_name

WorkingShift Table has shift_id, duration

Вопрос:

Допустим, я хотел бы обновить данные следующим образом :

Сотрудник FirstName = Stack, LastNa я = переполнение,

Отдел Идентификатор отдела = 4, Название отдела = Веб,

Сдвиг Сдвиг_id = 2,

Какое кодирование я должен выполнить, как указано выше?

1 Ответ

2 голосов
/ 04 марта 2020

Чтобы разрешить изменение отдела сотрудника: select d должно быть select e, чтобы получить сотрудника и обновить идентификатор отдела сотрудника, а не идентификатор записи отдела.

моя таблица отдела содержит название отдела, так что если я хочу обновить свое имя отдела, тогда я буду использовать команду «Выбрать, правильно ли я?»

Если вы действительно хотите изменить название этого отдела, вы можете выбрать подразделение и изменить его имя. Однако это зависит от того, что вы действительно хотите делать. Если сотрудник указывает на ID отдела = 1, name = "Department A", хотите ли вы изменить название этого отдела на "Department B", или уже существует отдел B с другим ID? (Т.е. 2) Если вы укажете для DepartmentID сотрудника значение «2», то соответствующие сведения об отделе будут поступать из отдела B, как правило, это именно то, что вам нужно. Если вы хотите изменить название отдела (и имя, которое отображается для всех сотрудников, связанных с идентификатором отдела 1), вы можете выбрать этот отдел и обновить его название.

Просмотр исходного кода:

var result = (from e in DSE.employees
              join d in DSE.departments on e.department_id equals d.department_id
              join ws in DSE.workingshifts on e.shift_id equals ws.shift_id
              where d.department_id == 1
              select d).FirstOrDefault();

if (result != null)
{
    result.department_id = 2;
    DSE.SaveChanges();
}

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

var employee = DSE.employees.Where(e => e.department_id == 1)
                 .FirstOrDefault();

if (employee != null)
{
    employee.department_id = 2;
    DSE.SaveChanges();
}

При использовании таких методов, как FirstOrDefault, вы всегда должны включать в себя предложение Order By type, чтобы гарантировать, что вы получите предсказуемый порядок для получения повторяемых результатов.

Если Вы действительно хотите обновить связанные данные, такие как название отдела:

var department = DSE.departments.Single(d => d.department_id == 1);
department.name = "New Name";
DSE.SaveChanges();

Здесь, потому что мы ожидаем, что только один и только 1 отдел будет иметь идентификатор 1, мы должны использовать Single вместо FirstOrDefault. Если ни один отдел не найден или найдено более одного отдела, он выдаст исключение. Лучше это исключение, говорящее о том, что найдено ноль или более строк, чем возвращение метода «OrDefault» и отключение на NullReferenceException в будущем.

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

С EF реальная сила заключается в отображении отношений через свойства навигации, поэтому вам не нужно выставлять свойства FK или вручную отображать соединения выражений, подобных вам будет в SQL. EF может управлять всем этим за кулисами. Вы можете загружать сущности и либо стремиться, либо лениво загружать связанные с ними сущности, такие как поиск обновлений данных, или просто выбирать поля из сущности и связанные с ней детали и позволить EF создать подходящую SQL.

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