Линк к сущностям многие ко многим присоединяются - PullRequest
2 голосов
/ 08 декабря 2011

Я впервые использую Entity Framework, поэтому я не уверен, правильно ли я это делаю.

У меня есть 4 таблицы:

CustomerOrder
------------
ID, StaffID, DeptID, Status, other columns...

Staff
------------
StaffID, other columns...

StaffDept
------------
StaffID, DeptID - only 2 fields

Dept
------------
DeptID, other columns...

Сотрудник может принадлежатьнесколько отделов.Таблица StaffDept предназначена только для хранения этого отношения «многие ко многим».

Мне нужно получить комбинацию из:

  • всех заказов клиентов, которые не имеют Status из «в процессе»
  • любые дополнительные записи для текущего сотрудника с Status «В процессе»
  • любые дополнительные записи с Status «В процессе», где сотрудник является сотрудником того же отделакак Заказ клиента.

Например, если у меня есть следующие данные:

Staff
-----
1, Mr X, ...
2, Mr Y, ...

Dept
-----
1, Sales, ...
2, Marketing, ...

StaffDept
-----
1, 1
1, 2
2, 2

CustomerOrder
-----
1, 1, 1, In Progress, ...
2, 1, 1, Completed, ...
3, 2, 2, In Progress, ...
4, 2, NULL, In Progress, ...

Я бы ожидал, что если бы текущий пользователь был # 1, он бы увидел заказы клиентов 1,2, 3.Пользователь № 2 увидит 2,3,4.Вот код, который у меня есть:

from co in CustomerOrders
where co.Status != "In Progress" 
  || co.StaffID == @CurrentStaffID
  || (co.StaffID != @CurrentStaffID 
      && co.DeptID!= null 
      && Staffs.Where(x => x.StaffID == @CurrentStaffID).FirstOrDefault().Depts.Any(x => x.DeptID== co.DeptID))
select new CustomerOrderObject
{
    Description = co.Description,
    Amount = co.Amount,
    ...
}

, который работает, но Resharper жалуется, что часть FirstOrDefault () будет выдавать исключение NULL во время выполнения.Я тестировал пользователя # 3 (который не существует) в Linqpad, и он не выдает ошибку - он возвращает только запись 2, чего я и ожидал.Решарпер хочет, чтобы я вытащил Staffs.Where(x => x.StaffID == 3).FirstOrDefault() в отдельный прогон запроса перед запросом выше, но я думаю, что это замедлит его?Я действительно не уверен, что какой-либо из этих запросов является самым быстрым способом получения данных, так как я новичок в linq для сущностей, я использую linq-to-sql.Буду признателен за любой совет - я даже не уверен, как правильно описать тип объединения, которое я пытаюсь сделать.

1 Ответ

2 голосов
/ 08 декабря 2011

Поскольку вы просто извлекаете члена Staff по его первичному ключу и знаете, что по этому идентификатору будет ровно один сотрудник, вы должны заменить FirstOrDefault на Single.

Staffs.Single(x => x.StaffID == @CurrentStaffID).Depts.Any(x => x.DeptID== co.DeptID))

Редактировать 1:

Возможно, вы можете немного сложить свой запрос:

StaffDept.Any(sd => sd.StaffId == @CurrentStaffID && sd.DeptID== co.DeptID)

Редактировать 2:

Staff.Any(x => x.StaffID == @CurrentStaffID && x.Depts.Any(d => d.DeptID == co.DeptID)
...