【问题标题】:Convert SQL query (with outer join and datediff) to LINQ将 SQL 查询(带有外连接和 datediff)转换为 LINQ
【发布时间】:2013-12-13 09:54:03
【问题描述】:

我有这个 SQL 查询需要转换为 LINQ。我是 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
                                   };

【问题讨论】:

    标签: c# sql linq outer-join


    【解决方案1】:

    这可能有一些错误,但可能会让你上路:

    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();
    

    【讨论】:

      【解决方案2】:

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

       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
                                         };
      

      【讨论】:

      • “??”是什么意思代表?这里,ambulance 是 Int16,officer_no 是 Int - 我该如何修改它?另外,我无法将其转换为 LINQ: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 &gt; '2013-05-30 21:48:04.000' or sd.time_off is null)
      • 啊你不想要??那么这基本上意味着使用左值,但如果它为空,则使用右值。
      • dateadd(d,-1,'2013-05-30 21:48:04.000') 中的硬编码日期从何而来?是在某个地方传递的,还是每次都一样?
      • 此查询在存储过程中...日期是一个参数
      • 我认为我在编辑中放置的东西应该可以做到。注意我假设你通过 DateTime.MinValue 因为 DateTime 不能为空。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多