0

私は次のコードを持っています、そしてコードの重複を避けようとしています 私がしたいのは「SelectGrouped」と呼ばれるカスタム拡張メソッドを持っていることです

これは「Shift」オブジェクトを受け入れ、匿名タイプを返します(可能かどうかはわかりません)

var groupedFillingsCurrentShift = currentShift.FilingMeasurements
                    .Where(f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == ShiftEnd)
                    .GroupBy(f => new { f.Medium, f.MeasurementTime })
                    .Select(t => new { t.Key.Medium, t.Key.MeasurementTime, VolumeInTanks = t.Sum(s => s.Filing) })
                    .ToList();


if (previousShift != null)
{
    var groupedFillingsPreviousShift = previousShift.FilingMeasurements
        .Where(f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == previousShift.ShiftEnd)
        .GroupBy(f => new { f.Medium, f.MeasurementTime })
        .Select(t => new { t.Key.Medium, t.Key.MeasurementTime, VolumeInTanks = t.Sum(s => s.Filing) })
        .ToList();

私が達成したいのは、そのように見えるようにすることです

var groupedResultCurrentShift = 
   currentShift.SelectGrouped(t=>t.Medium, t.MeasurementTime, t.VolumenInTanks);

var groupedResultPreviousShift = 
   previousShift.SelectGrouped(t=>t.Medium, t.MeasurementTime, t.VolumenInTanks);
4

2 に答える 2

2

残念ながら、あなたが望むことは現在の形ではできません。

まず、変数tはラムダでのみ値を持ちます。コンマはパラメーターを区切るtため、他のパラメーターの範囲を失います。

第 2 に、さらに重要なことに、匿名型は定義によってローカルにスコープされます。これは、匿名型を保持する変数の型を暗示するために「var」を使用する必要があるためです。それらをパラメーターとして渡すことも、戻り値として返すこともできません (まあ、技術的には を使用できますがdynamic、そこには行かないでください)。

投影されたデータの最終的な形式を保持するために使用できる名前付きの型を定義する場合、これは機能します。

internal class VolumeData
{
   public string Medium;
   public DateTime MeasurementTime;
   public decimal VolumeInTanks;
}

public static List<VolumeData> GetVolumeData(this Shift shift)
{
   return shift.FilingMeasurements
               .Where(f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == ShiftEnd)
               .GroupBy(f => new { f.Medium, f.MeasurementTime })
               .Select(t => new VolumeData{ 
                                Medium = t.Key.Medium, 
                                MeasurementTime = t.Key.MeasurementTime, 
                                VolumeInTanks = t.Sum(s => s.Filing) })
               .ToList();
}

...

var groupedFillingsCurrentShift = currentShift.GetVolumeData();


if (previousShift != null)
    var groupedFillingsPreviousShift = previousShift.GetVolumeData();
于 2012-08-17T20:32:39.983 に答える
0
var groupedResultCurrentShift = 
 currentShift.SelectGrouped(t=>t.Medium, t.MeasurementTime, t.VolumenInTanks);

t2 番目と 3 番目の節の が定義さVolumenInTanksれておらず、まだ作成していないプロパティに関連しているため、意味がありません。

Selectまた、クエリの が同じスコープで以前に定義された匿名オブジェクトに関連しているという問題もあります。これにより、何を選択するかを定義するラムダを渡すメソッドを定義できなくなります。

でも:

currentShift.FilingMeasurements
                .Where(f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == ShiftEnd)
                .GroupBy(f => new { f.Medium, f.MeasurementTime })
                .Select(t => new { t.Key.Medium, t.Key.MeasurementTime, VolumeInTanks = t.Sum(s => s.Filing) })
                .ToList();

と同等です。

currentShift.FilingMeasurements
                .Where(f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == ShiftEnd)
                .GroupBy(f => new { f.Medium, f.MeasurementTime }, s => s.Filing)
                .Select(t => new { t.Key.Medium, t.Key.MeasurementTime, VolumeInTanks = t.Sum() })
                .ToList();

さて、これはまだ完全ではありませんが、同じ情報を以下から取得すると考えてみましょう:

currentShift.FilingMeasurements
                .Where(f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == ShiftEnd)
                .GroupBy(f => new { f.Medium, f.MeasurementTime }, s => s.Filing)
                .Select(t => new { t.Key, VolumeInTanks = t.Sum() })
                .ToList();

そう。item.Key.Mediumではなく、喜んで行う必要がある場合item.Mediumは、ビジネスに取り組んでいます。

戻り値の型が必要なので、作成します。

public class GroupedCount<T>
{
  public<T> Key{get;set;}
  public int Count{get;set;}//bit more of a general-purpose name than VolumeInTanks
}

次に、メソッドを作成します。

public static List<GroupedCount<TKey>> ToGroupedCounts<TSource, TKey>(this IQueryable<TSource> source, Func<TSource, bool> pred, Func<TSource, TKey> keyGen, Func<TSource, int> tallyGen)
{
    currentShift.FilingMeasurements
                .Where(pred)
                .GroupBy(keyGen, tallyGen)
                .Select(t => new GroupedCount<TKey>{ Key = t.Key, Count = t.Sum() })
                .ToList();
}

次のように呼び出すことができます。

currentShift.ToGroupedCounts(
  f => TimeSpan.Parse(f.MeasurementTime.MeasurementTime) == ShiftEnd,
  f => new { f.Medium, f.MeasurementTime },
  s => s.Filing
);

これを汎用にしたいのでToList()、特定のケースで確実に必要でない限り呼び出すべきではないため、IQueryable を返す方が理にかなっています。

public static IQueryable<GroupedCount<TKey>> ToGroupedCounts<TSource, TKey>(this IQueryable<TSource> source, Func<TSource, bool> pred, Func<TSource, TKey> keyGen, Func<TSource, int> tallyGen)
{
    currentShift.FilingMeasurements
                .Where(pred)
                .GroupBy(keyGen, tallyGen)
                .Select(t => new GroupedCount<TKey>{ Key = t.Key, Count = t.Sum() });
}
于 2012-08-17T20:54:19.197 に答える