简体   繁体   中英

LINQ query returning no rows

I'm new to LINQ, so I'm sure there's an error in my logic below.

I have a list of objects:

class Characteristic
{
  public string Name { get; set; }
  public string Value { get; set; }
  public bool IsIncluded { get; set; }
}

Using each object in the list, I want to build a query in LINQ that starts with a DataTable , and filters it based on the object values, and yields a DataTable as the result.

My Code so far:

DataTable table = MyTable;
// Also tried: DataTable table = MyTable.Clone();

foreach (Characteristic c in characteristics)
{
  if (c.IsIncluded)
  {
    var q = (from r in table.AsEnumerable()
             where r.Field<string>(c.Name) == c.Value
             select r);

    table = rows.CopyToDataTable();
  }
  else
  {
    var q = (from r in table.AsEnumerable()
             where r.Field<string>(c.Name) != c.Value
            select r);

    table = q.CopyToDataTable();
  }
}

UPDATE

I was in a panicked hurry and I made a mistake; my DataTable was not empty, I just forgot to bind it to the DataGrid . But also, Henk Holterman pointed out that I was overwriting my result set each iteration, which was a logic error.

  • Henk's code seems to work the best so far, but I need to do more testing.

  • Spinon's answer also helped bring clarity to my mind, but his code gave me an error.

  • I need to try to understand Timwi's code better, but in it's current form, it did not work for me.

NEW CODE

DataTable table = new DataTable();

foreach (Characteristic c in characteristics)
{
  EnumerableRowCollection<DataRow> rows = null;

  if (c.IsIncluded)
  {
    rows = (from r in MyTable.AsEnumerable()
             where r.Field<string>(c.Name) == c.Value
             select r);
  }
  else
  {
    rows = (from r in MyTable.AsEnumerable()
             where r.Field<string>(c.Name) != c.Value
            select r);
  }

  table.Merge(rows.CopyToDataTable());
}

dataGrid.DataContext = table;

The logic in your posting is wonky; here is my attempt of what I think you are trying to achieve.

DataTable table = MyTable.AsEnumerable()
     .Where(r => characteristics.All(c => !c.IsIncluded ||
                                          r.Field<string>(c.Name) == c.Value))
     .CopyToDataTable();

If you actually want to use the logic in your posting, change || to ^ , but that seems to make little sense.

You overwrite the table variable for each characteristic, so in the end it only holds the results from the last round, and that that apparently is empty.

What you could do is something like:

// untested
var t = q.CopyToDataTable();
table.Merge(t);

And I suspect your query should use MyTable as the source:

var q = (from r in MyTable.AsEnumerable() ...

But that's not entirely clear.

If you are trying to just insert the rows into your table then try calling the CopyToDataTable method this way:

q.CopyToDataTable(table, LoadOption.PreserveChanges);

This way rather than reassigning the table variable you can just update it with the new rows that are to be inserted.

EDIT: Here is an example of what I was talking about:

DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Value", typeof(string));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM