将SQL查询(使用外连接和datediff)转换为LINQ

时间:2013-11-27 16:27:47

标签: c# sql linq outer-join

我有这个需要转换为LINQ的SQL查询。我是LINQ的新手,外连接使我很难将此查询转换为LINQ。

select distinct ls.crew, sd.ambulance, case_number from log_sheet ls
left outer join shift_detail sd on ls.crew = sd.crew 
and sd.time_on between dateadd(d,-1,'2013-05-30 21:48:04.000') and '2013-05-30 21:48:04.000' and (sd.time_off > '2013-05-30 21:48:04.000' or sd.time_off is null)
where ls.time_out between dateadd(d,-1,'2013-05-30 21:48:04.000') and '2013-05-30 21:48:04.000' and ('2013-05-30 21:48:04.000' <= ls.time_clear or ls.time_clear is null)
and (sd.ambulance = 58 or ls.crew = null)
union all
select distinct ls.crew, sd.ambulance, case_number from log_hist ls
left outer join shift_detail sd on ls.crew = sd.crew and sd.time_on between dateadd(d,-1,'2013-05-30 21:48:04.000') and '2013-05-30 21:48:04.000' and (sd.time_off > '2013-05-30 21:48:04.000' or sd.time_off is null)
where ls.time_out between dateadd(d,-1,'2013-05-30 21:48:04.000') and '2013-05-30 21:48:04.000' and ('2013-05-30 21:48:04.000' <= ls.time_clear or ls.time_clear is null)
and (sd.ambulance = 58 or ls.crew = null)

有人可以帮忙吗?我失败的尝试看起来像这样:

var shiftDetail = _dispatchRepository.FindQueryable<Domain.Model.ShiftDetail>();

            var logsheet = _repository.FindQueryable<Domain.Model.LogSheet>()
                .Where(ls => ((ls.time_out >= SqlFunctions.DateAdd("dd", -1, criteria.MRxIncident_Timestamp)) && (ls.time_out <= criteria.MRxIncident_Timestamp))
                        && (criteria.MRxIncident_Timestamp <= ls.time_clear || ls.time_clear == null) && (ls.crew==null));

            var shiftDetailQuery = from l in logsheet
                                   join sd in shiftDetail on l.crew equals sd.crewID into LeftJoin
                                   from sd in LeftJoin.DefaultIfEmpty()
                                   select new MRxCaseSearchResults
                                   {
                                       CaseNumber = l.case_number,
                                       Crew = l.crew,
                                       Ambulance = sd.ambulance,
                                       OfficerNo = sd.officer_no
                                   };

2 个答案:

答案 0 :(得分:0)

到目前为止你所拥有的部分应该更像(假设你的所有值都是字符串)

 var shiftDetailQuery = from l in logsheet
                                   join sd in shiftDetail on l.crew equals sd.crewID into LeftJoin
                                   (from sd_sub in LeftJoin.DefaultIfEmpty()
                                    where (sd_sub.time_on >= dateArg.addDays(-1) && sd_sub.time_on <= dateArg) && (sd_sub.time_off > dateArg || sd_sub.time_off == DateTime.MinValue))
                                   select new MRxCaseSearchResults
                                   {
                                       CaseNumber = l.case_number,
                                       Crew = l.crew,
                                       Ambulance = sd_sub.Ambulance ?? string.empty
                                       OfficerNo = sd_sub.officer_no ?? string.empty
                                   };

答案 1 :(得分:0)

这可能有一些错误,但可能会让你继续前进:

var dt = new DateTime(2013, 05, 30, 21, 48, 04);

var shiftDetailFiltered = _repository.FindQueryable<Domain.Model.ShiftDetail>()
    .Where(x => x.time_on >= dt.AddDays(-1)) && x.time_on <= dt)
    .Where(x => x.time_off == null || x.time_off > dt);

var q1 = _repository.FindQueryable<Domain.Model.LogSheet>()
.Join(shiftDetailFiltered, ls => ls.crew, sd => sd.crew, (ls, sd) => new { ls, sd })
.DefaultIfEmpty()
.Where(x => x.ls.time_out >= dt.AddDays(-1) && x.ls.time_out <= dt)
.Where(x => dt < x.ls.time_clear == null || x.ls.time_clear)
.Where(x => x.sd.ambulance == 58 || x.ls.crew == null)
.Select(x => new MRxCaseSearchResults
    { 
        CaseNumber = l.case_number,
        Crew = x.ls.crew, 
        Ambulance = x.sd.ambulance, 
        OfficerNo = x.ls.officer_no 
    })
.Distinct();


var q2 = _repository.FindQueryable<Domain.Model.LogHist>()
.Join(shiftDetailFiltered, ls => ls.crew, sd => sd.crew, (ls, sd) => new { ls, sd })
.DefaultIfEmpty()
.Where(x => x.ls.time_out >= dt.AddDays(-1) && x.ls.time_out <= dt)
.Where(x => dt < x.ls.time_clear == null || x.ls.time_clear)
.Where(x => x.sd.ambulance == 58 || x.ls.crew == null)
.Select(x => MRxCaseSearchResults
    { 
        CaseNumber = l.case_number,
        Crew = x.ls.crew, 
        Ambulance = x.sd.ambulance, 
        OfficerNo = x.ls.officer_no 
    })
.Distinct();

var union = q1.Union(q2);

var result = union.ToArray();