0

次の部分的なクエリがあります

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

1 に答える 1

1

まだあまり文脈がありませんが、とにかく適切な答えを推測します:)

SQL に変換されているクエリ式内で多くの作業を行おうとしている場合は、クエリを 2 つの部分に分割する方がよい場合があります。

  • 可能な限り多くのフィルタリングを行い、必要なデータのみを指定して、SQL で実行される部分ですが、「生の」形式です
  • 必要な .NET メソッドを使用できる LINQ to Objects で行われる部分。

AsEnumerableのメソッドの使用から のメソッドの使用に効果的に切り替えるために使用QueryableEnumerableます。だからあなたは持っているかもしれません:

var sqlQuery = from ...
               orderby ...
               select ...;

var finalQuery = sqlQuery.AsEnumerable().Select(entry => new { 
                     // Call whatever methods you like in here
                 });

これにより、次のようなものをエミュレートするために SQL を生成するように LINQ プロバイダーに依頼する必要がなくなります。

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)

于 2012-08-23T16:37:36.020 に答える