How to perform a Linq "First" query on a strongly-typed DataTable object?
I'm trying to perform a simple Linq "find first" query on a typed DataTable, but cannot seem to get the syntax correct.
(If I don't use typed data table/row objects, things work just fine.)
I have this...
class Program
{
static void Main(string[] args)
{
My开发者_StackOverflow中文版DataTable table = new MyDataTable("table");
table.Rows.Add(1, "Hello");
table.Rows.Add(2, "There");
table.Rows.Add(1, "World");
table.Rows[0].Delete();
Func<MyDataRow, Boolean> func = (row) => row.One == 1;
var row1 = table.AsEnumerable().First(func);
}
private class MyDataTable : DataTable
{
public MyDataTable()
{
this.Columns.Add("One", typeof(Int32));
this.Columns.Add("Two", typeof(String));
}
public MyDataTable(String tableName) : this() { this.TableName = tableName; }
protected override Type GetRowType()
{
return typeof(MyDataRow);
}
protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
{
return new MyDataRow(builder);
}
public IEnumerable<MyDataRow> AsEnumerable()
{
foreach (MyDataRow row in this.Rows)
{
yield return row;
}
}
}
private class MyDataRow : DataRow
{
internal MyDataRow(DataRowBuilder builder) : base(builder) { }
public int One
{
set { this["One"] = value; }
get { return Convert.ToInt32(this["One"]); }
}
public String Two
{
set { this["Two"] = value; }
get { return Convert.ToString(this["Two"]); }
}
}
}
I had tried this as well (which clearly didn't work);
private class MyDataTable : DataTable
{
:
public EnumerableRowCollection<MyDataRow> AsEnumerable()
{
return base.AsEnumerable();
}
}
So, my question is this:
In order to use Linq to determine the existence of one or more records in a typed data table, what do I need to implement ? Do I, for example, need to override "AsEnumerable", or could I write a "First" method on the MyDataTable class ?
Or do I have to do something cludgy like cast MyDataTable as a DataTable and treat the rows as DataRow objects ?
Thanks,
Use Cast to convert an IEnumerable
to strongly-typed IEnumerable<T>
.
First of all, your code seems to work here. row1 is not null.
If you want to check if a record exists, you would use the Linq method Any(r => r.One == 1).
Instead of writing your own implementation of AsEnumerable( )
you could reference the assembly System.Data.DataSetExtensions
Then you could do:
table.AsEnumerable( ).Where( item => item.Field<int>( "One" ) == 1 ).First( );
You need following using
statements:
using System.Data.Linq;
using System.Linq;
精彩评论