我有以下部分查询
var finalResults =
(from o in outerJoin
orderby o.timeKey.timeKey.Year_Num, o.timeKey.timeKey.Month, o.Key.Key.PlantId, o.timeKey.timeKey.PhysicalUnitId
select new
{
IndicatorName = IndicatorName,
LocationName = o.timeKey.timeKey.PlantId,
GroupingName = o.timeKey.timeKey.PhysicalUnitId,
Year = o.timeKey.timeKey.Year_Num,
Month = o.timeKey.timeKey.Month,
Numerator = o.timeKey.Key.Derate_Hours != null ? o.timeKey.Key.Derate_Hours ?? 0 : 0,
Denominator = o.timeKey.timeKey.Hours - o.timeKey.Key.Derate_Hours ?? 0,
Weight = o.timeKey.timeKey.NetMaximumCapacity,
}).ToList();
查询工作正常,但Month以格式给出了一个月份和年份:
August 2012
我需要这种格式:
08
我改变了我的代码,如下所示:
var finalResults =
(from o in outerJoin
orderby o.timeKey.timeKey.Year_Num, o.timeKey.timeKey.Month, o.Key.Key.PlantId, o.timeKey.timeKey.PhysicalUnitId
select new
{
IndicatorName = IndicatorName,
LocationName = o.timeKey.timeKey.PlantId,
GroupingName = o.timeKey.timeKey.PhysicalUnitId,
Year = o.timeKey.timeKey.Year_Num,
Month = DateTime.ParseExact(o.timeKey.timeKey.Month.Split(' ')[0], "MMMM", CultureInfo.CurrentCulture).Month,
Numerator = o.timeKey.Key.Derate_Hours != null ? o.timeKey.Key.Derate_Hours ?? 0 : 0,
Denominator = o.timeKey.timeKey.Hours - o.timeKey.Key.Derate_Hours ?? 0,
Weight = o.timeKey.timeKey.NetMaximumCapacity,
}).ToList();
但现在我收到以下错误:
Unrecognized expression node: ArrayIndex
有没有办法做我想做的事情?不能选择更改DB中的格式。
以下是整个查询:
protected IList<DataResults> QueryData(HarvestTargetTimeRangeUTC ranges)
{
using (var context = new DataClassesDataContext(_connectionString))
{
context.CommandTimeout = 240;
const string IndicatorName = "{DFD88372-FB87-49AC-8576-68DCBE7B00E8}";
List<string> typeCodes = new List<string>() { "D1", "D2", "D3", "DP", "PD", "DM", "D4" };
DataResults endItem = new DataResults();
List<DataResults> ListOfResults = new List<DataResults>();
var results =
(from v in context.vDimUnits
join vf in context.vFactEnergyAllocations on v.UnitKey equals vf.UnitKey
join vd in context.vDimGadsEvents on vf.GadsEventKey equals vd.GadsEventKey
join vt in context.vDimTimes on vf.TimeKey equals vt.TimeKey
where typeCodes.Contains(vd.GadsEventTypeCode)
&& vt.Year_Num >= ranges.StartTimeUTC.Year
&& vt.Year_Num <= ranges.EndTimeUTC.Year
&& v.PhysicalUnitId != "N/A"
&& v.PhysicalUnitId != "UNK"
&& v.PlantId != "UNK"
&& v.NercUnitType != "WT"
group vf by new { v.PlantId, v.PhysicalUnitId, v.NetDependableCapacity, vt.Year_Num, vt.Month } into groupItem
select new
{
groupItem.Key.Year_Num,
groupItem.Key.Month,
groupItem.Key.PhysicalUnitId,
groupItem.Key.NetDependableCapacity,
Derate_Hours = groupItem.Sum(x => (float?)x.AllocatedEnergyMwh / groupItem.Key.NetDependableCapacity),
groupItem.Key.PlantId,
Unit = groupItem.Count()
});
var resultHours =
(from f in
(from vt in context.vDimTimes
from v in context.vDimUnits
where vt.Year_Num >= ranges.StartTimeUTC.Year
&& vt.Year_Num <= ranges.EndTimeUTC.Year
&& v.PhysicalUnitId != "N/A"
&& v.PhysicalUnitId != "UNK"
&& v.PlantId != "UNK"
&& v.NercUnitType != "WT"
select new { v.PlantId, v.PhysicalUnitId, vt.Year_Num, vt.Month, vt.TimeKey, v.NetMaximumCapacity }).Distinct()
group f by new { f.PhysicalUnitId, f.Year_Num, f.Month, f.PlantId } into groupItem
select new
{
groupItem.Key.PhysicalUnitId,
groupItem.Key.Year_Num,
groupItem.Key.Month,
groupItem.Key.PlantId,
groupItem.First().NetMaximumCapacity,
Hours = groupItem.Count()
});
var serviceHrsResults =
(from v in context.vDimUnits
join vf in context.vFactEnergyAllocations on v.UnitKey equals vf.UnitKey
join vt in context.vDimTimes on vf.TimeKey equals vt.TimeKey
join vus in context.vDimUnitStates on vf.UnitStateKey equals vus.UnitStateKey
where vus.UnitStateType != "Active"
&& vt.Year_Num >= ranges.StartTimeUTC.Year
&& vt.Year_Num <= ranges.EndTimeUTC.Year
&& v.NetDependableCapacity != 0
&& v.PhysicalUnitId != "N/A"
&& v.PhysicalUnitId != "UNK"
&& v.PlantId != "UNK"
&& v.NercUnitType != "WT"
group vf by new { v.PlantId, vt.Year_Num, vt.Month, v.PhysicalUnitId, v.NetDependableCapacity } into groupItem
select new
{
groupItem.Key.Year_Num,
groupItem.Key.Month,
groupItem.Key.PhysicalUnitId,
groupItem.Key.NetDependableCapacity,
groupItem.Key.PlantId,
Unit = groupItem.Count()
});
var outerJoin1 =
(from h in resultHours
join u in results on new { h.PhysicalUnitId, h.Year_Num, h.Month } equals new { u.PhysicalUnitId, u.Year_Num, u.Month } into outer
from grouping in outer.DefaultIfEmpty()
select new { timeKey = h, Key = grouping });
var outerJoin2 =
(from h in resultHours
join s in serviceHrsResults on new { h.PhysicalUnitId, h.Year_Num, h.Month } equals new { s.PhysicalUnitId, s.Year_Num, s.Month } into outer2
from grouping in outer2.DefaultIfEmpty()
select new { timeKey = h, Key = grouping });
var outerJoin =
(from a in outerJoin1
join b in outerJoin2 on new { a.timeKey.PhysicalUnitId, a.timeKey.Year_Num, a.timeKey.Month } equals new
{
b.timeKey.PhysicalUnitId,
b.timeKey.Year_Num,
b.timeKey.Month
} into outer
from grouping in outer.DefaultIfEmpty()
select new { timeKey = a, Key = grouping }).Distinct();
var finalResults =
(from o in outerJoin
orderby o.timeKey.timeKey.Year_Num, o.timeKey.timeKey.Month, o.Key.Key.PlantId, o.timeKey.timeKey.PhysicalUnitId
select new
{
IndicatorName = IndicatorName,
LocationName = o.timeKey.timeKey.PlantId,
GroupingName = o.timeKey.timeKey.PhysicalUnitId,
Year = o.timeKey.timeKey.Year_Num,
Month = DateTime.ParseExact(o.timeKey.timeKey.Month.Split(' ')[0], "MMMM", CultureInfo.CurrentCulture).Month,
Numerator = o.timeKey.Key.Derate_Hours != null ? o.timeKey.Key.Derate_Hours ?? 0 : 0,
Denominator = o.timeKey.timeKey.Hours - o.timeKey.Key.Derate_Hours ?? 0,
Weight = o.timeKey.timeKey.NetMaximumCapacity,
}).ToList();
for (int counter = 0; counter < finalResults.Count; counter++)
{
var item = finalResults[counter];
endItem = new DataResults();
ListOfResults.Add(endItem);
endItem.IndicatorName = IndicatorName;
endItem.LocationName = item.LocationName;
endItem.GroupingName = item.GroupingName;
endItem.Year = item.Year;
endItem.Month = item.Month.ToString();
endItem.Numerator = item.Numerator;
endItem.Denominator = item.Denominator;
endItem.Weight = item.Weight.Value;
}
return ListOfResults;
}
}
答案 0 :(得分:1)
我们仍然没有太多的背景,但无论如何我会猜到一个合适的答案:)
如果您正在尝试在正在转换为SQL的查询表达式中执行大量工作,您可能会发现最好将查询拆分为两部分:
您使用AsEnumerable
有效地将Queryable
中的方法转换为Enumerable
中的方法。所以你可能有:
var sqlQuery = from ...
orderby ...
select ...;
var finalQuery = sqlQuery.AsEnumerable().Select(entry => new {
// Call whatever methods you like in here
});
这避免了要求LINQ提供程序生成SQL来模拟这样的事情:
DateTime.ParseExact(o.timeKey.timeKey.Month.Split(' ')[0], "MMMM",
CultureInfo.CurrentCulture).Month,
这也意味着您可以编写辅助方法,这些方法可以在查询之外轻松测试:
var finalQuery = sqlQuery.AsEnumerable().Select(entry => new {
Month = ConvertYearMonthToMonthNumber(entry.Month),
...
});
请注意,CultureInfo.CurrentCulture
很可能是错误的文化,除非您确实知道数据库中存储的数据与您的用户处于同一文化中,这可能不是不变的文化。我认为你更有可能想要使用不变文化......或者只是使用Calendar.MonthNames.IndexOf(month)
。