无法访问LINQ结果集中的列

时间:2013-12-11 04:59:15

标签: c# linq visual-studio datatable

我正在访问一个小型Access数据库并将一些表放在数据集中。然后,我需要使用LINQ查询这些表。我对LINQ很新,我不明白以下代码有什么问题:

DataTable cours = autOuvrDS.Tables["cours"];
DataTable etudiants = autOuvrDS.Tables["etudiants"];
DataTable resultats = autOuvrDS.Tables["resultats"];

IEnumerable<DataRow> query = from etudiant in etudiants.AsEnumerable()
                             join resultat in resultats.AsEnumerable()
                             on etudiant.Field<string>("matricule") equals resultat.Field<string>("matricule")
                             join cour in cours.AsEnumerable()
                             on resultat.Field<string>("sigle") equals cour.Field<string>("sigle")
                             select etudiant;

DataTable table = query.CopyToDataTable<DataRow>();

然后我循环遍历每一行以打印数据:

foreach (DataRow row in table.Rows)
        {
            Console.WriteLine(
                row.Field<string>("Prenom") + "\t\t" +
                row.Field<string>("Nom") + "\t\t" +
                row.Field<string>("Sigle") + "\t\t" +   /// PROGRAM CRASH HERE
                row.Field<string>("Cours") + "\t\t"
                );
        }

执行程序时出现以下错误:“附加信息:列'Sigle'不属于表。”

列“Sigle”是“cours”表的一部分,我已经加入了查询,所以我会考虑查询将从连接表中选择列,但似乎并非如此。那么如何从其他表中选择列?

2 个答案:

答案 0 :(得分:1)

您写道Sigle属于cours表,但在您的LINQ查询中,您只从etudiants表中选择数据:select etudiant。因此该列不能在您的输出中。仔细看看你的代码。

答案 1 :(得分:0)

您的查询正在加入三组DataRow个对象,然后选择其中一个DataRow个对象作为输出。生成的table对象包含仅源自etudiants源表的行。

如果您只想要列出的字段,可以声明一个结构来保存与此类似的结果:

public struct QueryResult
{
    public string Prenom;
    public string Nom;
    public string Sigle;
    public string Cours;
}

然后当你想运行查询时:

var query = 
    from etudiant in etudiants.AsEnumerable()
    join resultat in resultats.AsEnumerable()
    on etudiant.Field<string>("matricule") equals resultat.Field<string>("matricule")
    join cour in cours.AsEnumerable()
    on resultat.Field<string>("sigle") equals cour.Field<string>("sigle")
    select new QueryResult
    {
        Prenom = etudiant.Field<string>("Prenom"),
        Nom = etudiant.Field<string>("Nom"),
        Sigle = resultat.Field<string>("Sigle"),
        Cours = resultat.Field<string>("Cours")
    };

List<QueryResult> results = query.ToList();

foreach (QueryResult row in results)
{
    Console.WriteLine("{0}\t\t{1}\t\t{2}\t\t{3}\t\t",
        row.Prenom, row.Nom, row.Sigle, row.Cours
    );
}

您可以使用匿名类型,但前提是在创建实例的方法之外的任何位置都不使用结果。相信我,除非结果完全是单个方法的内部结构,否则声明结构会更简单。


使用DataTable实施进行更新:

这将执行相同的查询并生成一个DataTable,其中填充了结果中的一系列字段值:

var query = 
    from etudiant in etudiants.AsEnumerable()
    join resultat in resultats.AsEnumerable()
    on etudiant.Field<string>("matricule") equals resultat.Field<string>("matricule")
    join cour in cours.AsEnumerable()
    on resultat.Field<string>("sigle") equals cour.Field<string>("sigle")
    select new { etudiant, cour };


// Définir la structure de la table de sortie
DataTable table = new DataTable();
table.Columns.Add("Prenom", typeof(string));
table.Columns.Add("Nom", typeof(string));
table.Columns.Add("Sigle", typeof(string));
table.Columns.Add("Cours", typeof(string));

// Remplir la table de sortie à partir la requête
foreach (var row in query)
{
    DataRow newrow = table.NewRow();
    newrow["Prenom"] = row.etudiant.Field<string>("Prenom");
    newrow["Nom"] = row.etudiant.Field<string>("Nom");
    newrow["Sigle"] = row.cour.Field<string>("Sigle");
    newrow["Cours"] = row.cour.Field<string>("Cours");
    table.Rows.Add(newrow);
}

虽然在代码和实际运行时可能有一种更有效的方法来实现这一点,但事实上你被限制使用DataTable而不是更多以.NET为中心的格式是我的事情通常不会面对。