【问题标题】:Can't access column in LINQ resultset无法访问 LINQ 结果集中的列
【发布时间】:2013-12-11 04:59:14
【问题描述】:

我正在访问一个小型 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”表的一部分,我已将其与查询连接起来,因此我认为查询会从连接的表中选择列,但似乎并非如此。 . 那么如何从其他表中选择列呢??

【问题讨论】:

  • 只需将 berakpoint 放在 PROGRAM CRASH HERE 并检查您是否使用错误的列名访问或可能转换为错误的数据类型。

标签: c# linq visual-studio datatable


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您的查询将连接三组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 为中心的格式这一事实正常脸。

    【讨论】:

    • 这是可行的,但我需要将结果集放在 DataTable 中。我尝试将查询切换回“IEnumerable”而不是“var”,但是在第二次连接时出现错误:“无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'System .Collections.Generic.IEnumerable'。存在显式转换(您是否缺少演员表?)"
    • 为什么一定要有DataTable?这个DataTable应该有什么格式?
    • 实际上这是作业问题的一部分,要求将结果集放入 DataTable 中,因此除此之外没有真正重要的原因将其放入表中。我不太确定,表格的格式是什么意思?
    • format 我的意思是它应该有什么列,什么类型等等。没有格式的DataTable 基本上是没用的。我已经用产生DataTable 的代码更新了我的答案,但我绝不会在生产中建议这种代码。
    • 非常感谢您的帮助。很抱歉没有尽快指定格式,但列确实都是字符串类型。如果它不是生产代码也没关系,因为它仅用于学习目的。现在我想知道他们为什么要求我们将结果放入 DataTable 中,如果这是一个障碍。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多