Pregunta

Can I restructure the following into a more compact linq query, ideally without the introduction of a helper function?

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);
¿Fue útil?

Solución

Start out by creating a helper class to hold onto the data. (Your code doesn't have any problems using anonymous types, but if you want to refactor sections into methods it'll be much easier with a named class.)

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

Now that we have that out of the way the query is fairly straightforward.

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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top