Как можно объединить наборы данных из нескольких таблиц только с определенными столбцами в EF Core? - PullRequest
0 голосов
/ 26 апреля 2018

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

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

Исходя из фона MySQL / MSSQL, я написал бы что-то вроде этого:

SELECT s.Id, u.Name, a.SubmittedOn
FROM sadSurveys s
LEFT JOIN audits a ON s.AuditId = a.Id
LEFT JOIN users u ON s.UserId = u.Id
UNION
SELECT f.Id, u.Name, a.SubmittedOn
FROM funSurveys f
LEFT JOIN audits a ON f.AuditId = a.Id
LEFT JOIN users u ON f.UserId = t.Id

Однако, используя EF, я до сих пор...

var allSurveys = _context.Audits
            .Include(f => f.FunSurvey)
                .ThenInclude(u => u.User)
            .Include(s => s.SadSurvey)
                .ThenInclude(u => u.User)
            .ToList();

... но я не могу понять, как сопоставить его с DTO, потому что UserId / Name находится в разных объектах опроса, в зависимости от того, к какому опросу он относится, и он становится грязнымчто заставляет меня думать, что мой EF-код здесь не использует правильный подход.

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

1 Ответ

0 голосов
/ 26 апреля 2018

Эквивалентный запрос LINQ с использованием синтаксиса запроса в значительной степени совпадает с запросом SQL (с учетом особенностей LINQ):

var allSurveys = (
    from s in _context.SadSurveys
    join a in _context.Audits on s.AuditId equals a.Id
    into s_a from a in s_a.DefaultIfEmpty() // left join
    join u in _context.Users on s.UserId == u.Id
    into s_u from u in s_u.DefaultIfEmpty() // left join
    select new SurveyDTO { Id = s.Id, Name = u.Name, SubmittedOn = a.SubmittedOn }
    ).Concat(
    from s in _context.FunSurveys
    join a in _context.Audits on s.AuditId equals a.Id
    into s_a from a in s_a.DefaultIfEmpty() // left join
    join u in _context.Users on s.UserId == u.Id
    into s_u from u in s_u.DefaultIfEmpty() // left join
    select new SurveyDTO { Id = s.Id, Name = u.Name, SubmittedOn = a.SubmittedOn }
    ).ToList();

Однако свойства ORM и навигации позволяют достичь того жерезультат с гораздо более простым запросом LINQ:

var allSurveys = ( 
    from s in _context.SadSurveys
    select new SurveyDTO { Id = s.Id, Name = s.User.Name, SubmittedOn = s.Audit.SubmittedOn }
    ).Concat(
    from s in _context.FunSurveys
    select new SurveyDTO { Id = s.Id, Name = s.User.Name, SubmittedOn = s.Audit.SubmittedOn })
    ).ToList();
...