2013-12-11 3 views
1

Я получаю доступ к небольшой базе данных Access и помещаю некоторые таблицы в набор данных. Затем мне нужно запросить эти таблицы с LINQ. Я довольно новый с 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», к которой я присоединился к запросу, поэтому я бы хотел, чтобы запрос выберет столбцы из объединенных таблиц, но, похоже, это не так .. Так как я могу выбрать столбцы из других таблиц?

+0

просто введите berakpoint в ПРОГРАММУ CRASH ЗДЕСЬ и проверьте, что вы обращаетесь с неправильным именем столбца или можете переходить к неправильному типу данных. – YOusaFZai

ответ

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 
    ); 
} 

You может использовать анонимный тип, но только если результаты не используются вне метода, который создает экземпляр. Поверьте мне в этом, проще объявить структуры, если результаты не будут полностью внутренними по отношению к одному методу.


Обновление с 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-ориентированной формы на что-то, с чем я обычно не сталкивался.

+0

Это работает, но мне нужно поставить набор результатов внутри DataTable. Я попытался переключить запрос на «IEnumerable » вместо «var», но затем я получаю сообщение об ошибке во втором соединении: «Невозможно неявно преобразовать тип« System.Collections.Generic.IEnumerable <> »в« System.Collections » .Generic.IEnumerable . Явное преобразование существует (вы пропускаете листинг?) « – SimCity

+0

Почему у вас должен быть« DataTable »? Какой формат должен иметь этот «DataTable»? – Corey

+0

На самом деле это часть проблемы с домашним заданием, которая просит поставить resulset внутри DataTable, поэтому нет никакой реальной причины, кроме этого, чтобы помещать ее в таблицу. Я не слишком уверен, что вы имеете в виду формат таблицы? – SimCity

1

Вы писали, что Sigle принадлежит таблице cours, но в вашем запросе LINQ вы выбираете данные только из etudiants table: select etudiant. Так что колонка не может быть в вашем выходе. Посмотрите внимательно на свой код.

Смежные вопросы