将多个 linq 查询和串联结果合并到一个较小的查询中



我可以将以下内容重组为更紧凑的 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);

首先创建一个帮助程序类来保存数据。 (您的代码使用匿名类型没有任何问题,但是如果您想将节重构为方法,使用命名类会容易得多。

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);

最新更新