0

理想的にはヘルパー関数を導入せずに、以下をよりコンパクトなlinqクエリに再構築できますか?

var revPerUnitChanges = 
    from row in this.DataTable.GetChanges(DataRowState.Modified).AsEnumerable()
    let field = "Rev/Unit"
    select new {
        Field = field,
        From = row.Field<decimal>(field, DataRowVersion.Original),
        To = row.Field<decimal>(field, DataRowVersion.Current),
        ItemIds = row.Field<string>("ItemIds"),};
var costPerUnitChanges = 
    from row in this.DataTable.GetChanges(DataRowState.Modified).AsEnumerable()
    let field = "Cost/Unit"
    select new {
        Field = field,
        From = row.Field<decimal>(field, DataRowVersion.Original),
        To = row.Field<decimal>(field, DataRowVersion.Current),
        ItemIds = row.Field<string>("ItemIds"), };
var numUnitsChanges = 
    from row in this.DataTable.GetChanges(DataRowState.Modified).AsEnumerable()
    let field = "Units"
    select new {
        Field = field,
        From = row.Field<decimal>(field, DataRowVersion.Original),
        To = row.Field<decimal>(field, DataRowVersion.Current),
        ItemIds = row.Field<string>("ItemIds"), };
var changes = 
    revPerUnitChanges
        .Concat(costPerUnitChanges
        .Concat(numUnitsChanges))
        .Where(c => c.From != c.To);
4

1 に答える 1

1

データを保持するヘルパー クラスを作成することから始めます。(コードで匿名型を使用しても問題はありませんが、セクションをメソッドにリファクタリングする場合は、名前付きクラスを使用するとはるかに簡単になります。)

public class MyClass //TODO give better name
{
    public MyClass(DataRow row, string field) //You could have a public static generate method if it doesn't make sense for this to be a constructor.
    {
        Field = field;
        From = row.Field<decimal>(field, DataRowVersion.Original);
        To = row.Field<decimal>(field, DataRowVersion.Current);
        ItemIds = row.Field<string>("ItemIds");
    }
    public string Field { get; set; }
    public decimal From { get; set; }
    public decimal To { get; set; }
    public string ItemIds { get; set; }
}

邪魔にならないようになったので、クエリはかなり簡単です。

var changes = dataTable.GetChanges(DataRowState.Modified)
    .AsEnumerable()
    .Select(row => new[]{ //create 3 new items for each row
                    new MyClass(row, "Rev/Unit"),
                    new MyClass(row, "Cost/Unit"),
                    new MyClass(row, "Units"),
                })
    .SelectMany(item => item) //flatten the inner array
    .Where(item => item.From != item.To);
于 2012-09-14T19:15:20.393 に答える