Ваше требование:
, если пользователь является менеджером, тогда получите его заявки, но если дилер получит его приложения, включая его дочерние приложения.
Я не уверен, вы используете структуру объекта или нет. Если это так, вы усложняете свою жизнь, потому что вы отклоняетесь от соглашений о структуре сущностей
Вы говорите, что у каждого пользователя ноль или более ChildUsers, а у каждого пользователя ноль или один ParentUser, ссылается по внешнему ключу ParentUserId.
Аналогично существует отношение один-ко-многим между Пользователями и Приложениями: каждый Пользователь имеет ноль или более Приложений, каждое Приложение принадлежит ровно одному Пользователю, на который ссылается внешний ключ UserId.
Правильный способ записи этих отношений в Entity Framework будет выглядеть следующим образом:
class User
{
public int UserId {get; set;}
// every User has zero or more Applications (one-to-many)
public virtual ICollection<Application> Applications {get; set;}
// every User has zero or more ChildUsers (one-to-many)
public virtual ICollection<User> ChildUsers {get; set}
// every User belongs to zero or one ParentUser, using foreign key
public int ParentUserId {get; set;}
public virtual User ParentUser {get; set;}
... // all other properties are not important in your question.
}
, если пользователь является Manager, тогда получают его приложения, но если Дилер получает его приложения, включая его дочерние приложения.
Если пользователь является менеджером, как вы хотите, чтобы приложения с дочерними приложениями: как одна последовательность приложений или как одна последовательность приложений, где каждое приложение имеет ноль или более дочерних приложений? ?
Не важно, как вы решаете, Пользователь является менеджером или нет, давайте предположим, что у пользователя есть свойство:
public bool IsManager {get => ...}
IQueryable<User> Users = ClientDbContext.Users
// only if you don't want all Users:
.Where(user => ...)
Идея состоит в том, чтобы создать две группы пользователей: менеджеры и другие. Если пользователь не является менеджером, мы выберем запрошенные свойства, включая приложения; если пользователь - менеджер, мы также выберем дочерние приложения.
var result = Users.Select(user => new
{
// Select the properties that both Managers and Others need:
Id = user.Id,
Name = user.Name
...
Applications = User.Applications.Select(application => new
{
// Select the application properties that you plan to use:
Id = application.Id,
...
// not needed: you already know the value
// UserId = application.UserId,
},
// if the user is a Manager, add the ChildApplications, otherwise add empty collection
ChildApplications = (User.IsManager ?
User.ChildUsers.SelectMany(childUser => childUser.Applications) :
Enumerable.Empty<Application>())
.Select(childApplication => new
{
// select the properties that you want from the child application
})
.ToList(),
});
Посмотрим на часть:
ChildApplications = (User.IsManager ?
User.ChildUsers.SelectMany(childUser => childUser.Applications) :
Enumerable.Empty<Application>())
Эта часть проверяет, является ли пользователь менеджером. Таким образом, он принимает все Приложения от всех ChildUsers как одну большую последовательность (SelectMany вместо Select). Если пользователь не является менеджером, он берет пустую коллекцию приложений.
Из каждого приложения в результате (либо из коллекции всех приложений ChildUsers, либо из пустой коллекции) мы выбираем свойства, которые вы want.
Хотя это работает, это не очень эффективно, потому что IsManager вызывается один раз для каждого приложения. Подумайте о создании двух запросов: один для менеджеров и один для других. Не выполняйте запрос, но выберите те же свойства и выполните запросы. Затем выполните их, чтобы убедиться, что к вашей СУБД обращаются только один раз.