用LINQ模拟SQL外部应用

i5desfxk  于 2024-01-03  发布在  其他
关注(0)|答案(1)|浏览(192)

我在将下面的存储过程翻译成LINQ时遇到了一些麻烦。

  1. SELECT DISTINCT a0.[recid] AS 'Id'
  2. ,a0.[latitude] AS 'Latitude'
  3. ,a0.[longitude] AS 'Longitude'
  4. ,a0.[countryregionid] AS 'CountryCode'
  5. ,a0.[level_] as 'Level'
  6. ,case
  7. when wht.[disinfection] is null
  8. then 0
  9. else wht.[disinfection]
  10. end as 'Disinfection'
  11. ,case when wd1.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd1.[fromtime] * 1000, 0), 108) end as 'MondayOpen'
  12. ,case when wd1.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd1.[totime] * 1000, 0), 108) end as 'MondayClose'
  13. ,case when wd2.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd2.[fromtime] * 1000, 0), 108) end as 'TuesdayOpen'
  14. ,case when wd2.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd2.[totime] * 1000, 0), 108) end as 'TuesdayClose'
  15. ,case when wd3.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd3.[fromtime] * 1000, 0), 108) end as 'WednesdayOpen'
  16. ,case when wd3.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd3.[totime] * 1000, 0), 108) end as 'WednesdayClose'
  17. ,case when wd4.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd4.[fromtime] * 1000, 0), 108) end as 'ThursdayOpen'
  18. ,case when wd4.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd4.[totime] * 1000, 0), 108) end as 'ThursdayClose'
  19. ,case when wd5.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd5.[fromtime] * 1000, 0), 108) end as 'FridayOpen'
  20. ,case when wd5.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd5.[totime] * 1000, 0), 108) end as 'FridayClose'
  21. ,case when wd6.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd6.[fromtime] * 1000, 0), 108) end as 'SaturdayOpen'
  22. ,case when wd6.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd6.[totime] * 1000, 0), 108) end as 'SaturdayClose'
  23. ,case when wd7.[fromtime] is null then '' else CONVERT(varchar, DATEADD(ms, wd7.[fromtime] * 1000, 0), 108) end as 'SundayOpen'
  24. ,case when wd7.[totime] is null then '' else CONVERT(varchar, DATEADD(ms, wd7.[totime] * 1000, 0), 108) end as 'SundayClose'
  25. FROM [dbo].[address] AS a0
  26. LEFT JOIN GIR_WashhouseTable as wht on wht.[recid] = a0.[addrrecid]
  27. OUTER APPLY(
  28. SELECT TOP 1
  29. awt0.[fromtime]
  30. , awt0.[totime]
  31. FROM [GIR_AddressWorkTime] as awt0
  32. WHERE awt0.[dataareaid] = 'v22'
  33. AND awt0.[active] = 1
  34. AND awt0.[weekday] = 1
  35. AND awt0.[refrecid] = a0.[recid]
  36. ) as wd1
  37. OUTER APPLY(
  38. SELECT TOP 1
  39. awt0.[fromtime]
  40. , awt0.[totime]
  41. FROM [GIR_AddressWorkTime] as awt0
  42. WHERE awt0.[dataareaid] = 'v22'
  43. AND awt0.[active] = 1
  44. AND awt0.[weekday] = 2
  45. AND awt0.[refrecid] = a0.[recid]
  46. ) as wd2
  47. OUTER APPLY(
  48. SELECT TOP 1
  49. awt0.[fromtime]
  50. , awt0.[totime]
  51. FROM [GIR_AddressWorkTime] as awt0
  52. WHERE awt0.[dataareaid] = 'v22'
  53. AND awt0.[active] = 1
  54. AND awt0.[weekday] = 3
  55. AND awt0.[refrecid] = a0.[recid]
  56. ) as wd3
  57. OUTER APPLY(
  58. SELECT TOP 1
  59. awt0.[fromtime]
  60. , awt0.[totime]
  61. FROM [GIR_AddressWorkTime] as awt0
  62. WHERE awt0.[dataareaid] = 'v22'
  63. AND awt0.[active] = 1
  64. AND awt0.[weekday] = 4
  65. AND awt0.[refrecid] = a0.[recid]
  66. ) as wd4
  67. OUTER APPLY(
  68. SELECT TOP 1
  69. awt0.[fromtime]
  70. , awt0.[totime]
  71. FROM [GIR_AddressWorkTime] as awt0
  72. WHERE awt0.[dataareaid] = 'v22'
  73. AND awt0.[active] = 1
  74. AND awt0.[weekday] = 5
  75. AND awt0.[refrecid] = a0.[recid]
  76. ) as wd5
  77. OUTER APPLY(
  78. SELECT TOP 1
  79. awt0.[fromtime]
  80. , awt0.[totime]
  81. FROM [GIR_AddressWorkTime] as awt0
  82. WHERE awt0.[dataareaid] = 'v22'
  83. AND awt0.[active] = 1
  84. AND awt0.[weekday] = 6
  85. AND awt0.[refrecid] = a0.[recid]
  86. ) as wd6
  87. OUTER APPLY(
  88. SELECT TOP 1
  89. awt0.[fromtime]
  90. , awt0.[totime]
  91. FROM [GIR_AddressWorkTime] as awt0
  92. WHERE awt0.[dataareaid] = 'v22'
  93. AND awt0.[active] = 1
  94. AND awt0.[weekday] = 7
  95. AND awt0.[refrecid] = a0.[recid]
  96. ) as wd7
  97. WHERE a0.[dataareaid] = 'v22'
  98. AND a0.[active] = 1
  99. AND a0.[level_] <> 0
  100. AND a0.[type] = 153
  101. AND a0.[ADDRTABLEID] = 52411
  102. AND a0.[countryregionid] IN
  103. ('AT', 'BE', 'BG', 'HR', 'CZ', 'EE', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'LI', 'MC', 'SM', 'CH', 'GB', 'DK') -- AIO-833
  104. order by COUNTRYREGIONID

字符串
所以这里的问题是外部应用。我已经研究了通过LINQ模仿外部应用的方法,并看到let关键字可以帮助你做到这一点。但在我的情况下,它并不有用。所以我试着这样做。

  1. var query =
  2. from address in _context.Address
  3. join washHouse in _context.GirWashhousetable
  4. on address.Addrrecid equals washHouse.Recid into whtGroup
  5. from washHouse in whtGroup.DefaultIfEmpty()
  6. join workTime in _context.GirAddressworktime
  7. on address.Recid equals workTime.Refrecid into workTimeGroup
  8. from workTime in workTimeGroup.DefaultIfEmpty()
  9. where address.Dataareaid == "v22"
  10. && address.Active == 1
  11. && address.Level != 0
  12. && address.Type == 153
  13. && address.Addrtableid == 52411
  14. && _countryCodesForWashStations.Contains(address.Countryregionid)
  15. && workTime.Dataareaid == "v22"
  16. && workTime.Active == 1
  17. let mondayWorkTime = workTimeGroup.FirstOrDefault(wt => wt.Weekday == 1)
  18. // Repeat similar logic for other days...
  19. select new WashingStationsResult
  20. {
  21. Id = address.Recid,
  22. Latitude = address.Latitude,
  23. Longitude = address.Longitude,
  24. CountryCode = address.Countryregionid,
  25. Level = address.Level,
  26. Disinfection = washHouse.Disinfection,
  27. MondayOpen = mondayWorkTime != null ? TimeSpan.FromSeconds(mondayWorkTime.Fromtime).ToString(@"hh\:mm\:ss") : string.Empty,
  28. MondayClose = mondayWorkTime != null ? TimeSpan.FromSeconds(mondayWorkTime.Totime).ToString(@"hh\:mm\:ss") : string.Empty,
  29. // Repeat similar logic for other days...
  30. };


如果只有一个let,它可以工作,但如果我在其他日子重复一些,我也会得到空列表作为响应。我不知道为什么。有人能建议什么是解决这个问题的最佳方法吗?

v1l68za4

v1l68za41#

对于OUTER APPLY,您必须使用不同的技术:集合选择器在非where情况下引用外部

  1. var query =
  2. from address in _context.Address
  3. join washHouse in _context.GirWashhousetable
  4. on address.Addrrecid equals washHouse.Recid into whtGroup
  5. from washHouse in whtGroup.DefaultIfEmpty()
  6. from mondayWorkTime in _context.GirAddressworktime
  7. .Where(workTime => address.Recid == workTime.Refrecid
  8. && workTime.Dataareaid == "v22"
  9. && workTime.Active == 1
  10. )
  11. .Take(1)
  12. .DefaultIfEmpty()
  13. // Repeat similar logic for other days...
  14. where address.Dataareaid == "v22"
  15. && _countryCodesForWashStations.Contains(address.Countryregionid)
  16. && address.Active == 1
  17. && address.Level != 0
  18. && address.Type == 153
  19. && address.Addrtableid == 52411
  20. select new WashingStationsResult
  21. {
  22. Id = address.Recid,
  23. Latitude = address.Latitude,
  24. Longitude = address.Longitude,
  25. CountryCode = address.Countryregionid,
  26. Level = address.Level,
  27. Disinfection = washHouse.Disinfection,
  28. MondayOpen = mondayWorkTime != null ? TimeSpan.FromSeconds(mondayWorkTime.Fromtime).ToString(@"hh\:mm\:ss") : string.Empty,
  29. MondayClose = mondayWorkTime != null ? TimeSpan.FromSeconds(mondayWorkTime.Totime).ToString(@"hh\:mm\:ss") : string.Empty,
  30. // Repeat similar logic for other days...
  31. };

字符串
为了简化查询,您可以使用预定义的过滤器准备记录:

  1. var workTimes = _context.GirAddressworktime
  2. .Where(workTime =>
  3. && workTime.Dataareaid == "v22"
  4. && workTime.Active == 1
  5. );
  6. var query =
  7. from address in _context.Address
  8. join washHouse in _context.GirWashhousetable
  9. on address.Addrrecid equals washHouse.Recid into whtGroup
  10. from washHouse in whtGroup.DefaultIfEmpty()
  11. from mondayWorkTime in workTimes
  12. .Where(workTime => address.Recid == workTime.Refrecid && workTime.WeekDay == 1)
  13. .Take(1)
  14. .DefaultIfEmpty()
  15. // Repeat similar logic for other days...
  16. where address.Dataareaid == "v22"
  17. && _countryCodesForWashStations.Contains(address.Countryregionid)
  18. && address.Active == 1
  19. && address.Level != 0
  20. && address.Type == 153
  21. && address.Addrtableid == 52411
  22. select new WashingStationsResult
  23. {
  24. Id = address.Recid,
  25. Latitude = address.Latitude,
  26. Longitude = address.Longitude,
  27. CountryCode = address.Countryregionid,
  28. Level = address.Level,
  29. Disinfection = washHouse.Disinfection,
  30. MondayOpen = mondayWorkTime != null ? TimeSpan.FromSeconds(mondayWorkTime.Fromtime).ToString(@"hh\:mm\:ss") : string.Empty,
  31. MondayClose = mondayWorkTime != null ? TimeSpan.FromSeconds(mondayWorkTime.Totime).ToString(@"hh\:mm\:ss") : string.Empty,
  32. // Repeat similar logic for other days...
  33. };

展开查看全部

相关问题