Как преобразовать этот оператор SQL в выражение Lambda / Linq - PullRequest
0 голосов
/ 11 января 2019

Я ищу эквивалентное лямбда-выражение LINQ для этого оператора SQL.

SELECT A.USER_ID, A.GIVEN_NAME, A.SURNAME, A.REGION, A.EMAIL 
FROM USER A
WHERE A.USER_ID IN (
    SELECT B.USER_ID_TXT 
    FROM TRAINING_COURSE B
    WHERE B.COURSE_ID_TXT IN 
        (SELECT C.MITT_COURSE_ID_TXT 
            FROM TRAINING_MITT C 
            WHERE C.TRAINING_ID =
                (SELECT D.TRAINING_ID 
                 FROM TRAINING_ROLE D 
                 WHERE D.ROLE_ID = 3011)))

Вот сущности. Я добавил несколько комментариев, чтобы проиллюстрировать ссылку на ТАБЛИЦЫ и ПОЛЯ в запросе SQL.

В этой таблице хранится информация о пользователях, и она монтируется как материализованное представление.

// TABLE USER 
public class TCUser
{
    // Field USER_ID
    public string UserId { get; set; }
    public string GivenName { get; set; }
    public string Surname { get; set; }
    public string OfficeBuilding { get; set; }
    public string Address { get; set; }
    public string FloorLocation { get; set; }
    public string FloorNumber { get; set; }
    public string Region { get; set; }
    public string Province { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }
    public string Email { get; set; }
}  

Следующий учебный курс магазина таблиц, и он прибывает из внешнего источника Это в основном импорт данных.

// TABLE TRAINING_COURSE - EXTERNAL SOURCE
public class TrainingCourse
{
    // Field USER_ID_TXT
    public String UserId { get; set; }

    // Field COURSE_ID_TXT
    public String CourseId { get; set; }
    public String CourseDescription { get; set; }
    public String ScheduleId { get; set; }
    public String ScheduleDescription { get; set; }
    public DateTime? ScheduleStartDate { get; set; }
    public DateTime? ScheduleEndDate { get; set; }
    public String Status { get; set; }
}

Эта таблица объединяет учебные курсы, необходимые для выполнения роли.

// TABLE TRAINING_ROLES - XREF between TRAINING_MITT and ICS_ROLE
public class IcsTrainingRole
{
     // Field ROLE_ID
     public int RoleId { get; set; }

     // Field TRAINING_ID
     public int TrainingId { get; set; }
     public virtual IcsTraining IcsTraining { get; set; }
     public virtual IcsRole IcsRole { get; set; }
}

В этой таблице приведена ассоциация обучения с внешней базой данных обучения MITT

// TABLE TRAINING_MITT
public class IcsTrainingMitt
{
    // Field TRAINING_ID             
    public int TrainingId { get; set; }

    // Field MITT_COURSE_ID_TXT
    public string MittCourseId { get; set; }
    public virtual IcsTraining IcsTraining { get; set; }
}

public class IcsTraining
{
    public int TrainingId { get; set; }
    public string TrainingName { get; set; }
    public virtual ICollection<IcsTrainingRole> IcsTrainingRoles { get; set; }
    public virtual ICollection<IcsTrainingMitt> IcsTrainingMitt { get; set; }
}


public class IcsRole
{
    public int RoleId { get; set; }
    public int SectionId { get; set; }
    public string RoleName { set; get; }
    public virtual ICollection<IcsTrainingRole> IcsTrainingRoles { get; set; }
}

Ответы [ 3 ]

0 голосов
/ 14 января 2019

Использование синтаксиса запроса Linq с вашими модельными классами с помощью объединений (согласно предложению Хогана):

var users = from u in TCUser
            join tc in TrainingCourse on u.UserId equals tc.UserId
            join tm in IcsTrainingMitt on tc.CourseId equals tm.MittCourseId
            join tr in IcsTrainingRole on tm.TrainingId equals tr.TrainingId
            where tr.RoleId == 3011
            select new
            {
                UserId = u.UserId,
                GivenName = u.GivenName,
                Surname = u.Surname,
                Email = u.Email
            };

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

0 голосов
/ 14 января 2019

Хорошо, использование объединения эффективно проще, и, основываясь на сообщении @kaffekopp, эквивалентное выражение с использованием лямбды будет:

var users = TCUser
    .Join(TrainingCourse, u => u.UserId, tc => tc.UserId, (u, tc) => new {u, tc})
    .Join(IcsTrainingMitt, @t => @t.tc.CourseId, tm => tm.MittCourseId, (@t, tm) => new {@t, tm})
    .Join(IcsTrainingRole, @t => @t.tm.TrainingId, tr => tr.TrainingId, (@t, tr) => new {@t, tr})
    .Where(@t => @t.tr.RoleId == 3011)
    .Select(@t => new
    {
        UserId = @t.@t.@t.u.UserId,
        GivenName = @t.@t.@t.u.GivenName,
        Surname = @t.@t.@t.u.Surname,
        Email = @t.@t.@t.u.Email
    });
0 голосов
/ 11 января 2019

Если вы переписываете код с помощью объединений, он будет выглядеть так:

SELECT A.USER_ID, A.GIVEN_NAME, A.SURNAME, A.REGION, A.EMAIL 
FROM USER A
JOIN TRAINING_COURSE B ON A.USER_ID = B.USER_ID_TXT
JOIN TRAINING_MITT C ON B.COURSE_ID_TXT = C.MITT_COURSE_ID
JOIN TRAINING_ROLE D ON C.TRAINING_ID = D.TRAINING_ID AND D.ROLE_ID = 3011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...