如何仅使用EF Core中的某些列连接多个表中的数据集?

时间:2018-04-26 00:29:56

标签: c# entity-framework linq entity-framework-core ef-core-2.0

所以我有悲伤的调查和有趣的调查,他们被记录在他们自己的表中。每个都附有审计数据。因此,调查包含在审计表中记录的外键。

我正在建立一个网页,列出所有已提交的调查。调查ID,用户名和提交日期。

来自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 :(得分:3)

使用查询语法的等效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();