2010-10-14 5 views
0

J'essaie d'effectuer une simple requête Linq "trouver d'abord" sur un DataTable typé, mais ne semble pas obtenir la syntaxe correcte.Comment effectuer une requête Linq "First" sur un objet DataTable fortement typé?

(Si je ne pas utiliser des objets table de données typées/ligne, les choses fonctionnent très bien.)

Je ... ce

class Program 
{ 
    static void Main(string[] args) 
    { 
    MyDataTable 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"]); } 
    } 
    } 
} 

J'avais essayé cela aussi (qui n'a clairement pas fonctionné);

private class MyDataTable : DataTable 
    { 
     : 
    public EnumerableRowCollection<MyDataRow> AsEnumerable() 
    { 
     return base.AsEnumerable(); 
    } 

    } 

Alors, ma question est la suivante:

Pour utiliser LINQ pour déterminer l'existence d'un ou plusieurs enregistrements dans un tableau de données typé, que dois-je mettre en œuvre? Dois-je, par exemple, remplacer "AsEnumerable", ou puis-je écrire une méthode "First" sur la classe MyDataTable?

Ou est-ce que je dois faire quelque chose de claudieux, comme lancer MyDataTable en tant que DataTable et traiter les lignes comme des objets DataRow?

Merci,

Répondre

0

Tout d'abord, votre code semble fonctionner ici. row1 n'est pas nul.

Si vous souhaitez vérifier si un enregistrement existe, vous devez utiliser la méthode Linq Any (r => r.One == 1).

+0

Mes excuses. Il a fallu un certain temps pour arriver à ce point et j'ai dû manquer le point qu'il a compilé. –

2

Utilisez Cast pour convertir un IEnumerable en type fortement typé IEnumerable<T>.

+0

Le IEnumerable retourné dans sa fonction est déjà fortement typé, sinon le code ne compilerait pas car .One serait inconnu. – testalino

0

Au lieu d'écrire votre propre implémentation de AsEnumerable() vous pouvez faire référence à l'ensemble System.Data.DataSetExtensions

Ensuite, vous pouvez faire:

table.AsEnumerable().Where(item => item.Field<int>("One") == 1).First(); 

indispensable après using déclarations:

using System.Data.Linq; 
using System.Linq; 
Questions connexes