2013-02-26 7 views
0

Я пытаюсь выбрать число DataRows только с указанными полями из запроса Linq, а затем использовать эти DataRows для заполнения DataTable. Проблема в том, что когда я добавляю эти DataRows в новый DataTable, я ожидаю, что и поле ID, и Name будут заполнены соответственно. Однако поле ID в DataTable содержит значения ID и Name. Может кто-то указать, что я делаю неправильно.Выберите определенные поля из запроса Linq и заполните DataTable

Вот код:

var query2 = from s in Tables[Table_Sec].AsEnumerable() 
      where query.Contains(s["sectype"]) 
      select new { id = s["id"], name = s["name"] }; // I only want these fields 



DataTable dt = new DataTable(); // Create my new dataTable 
dt.Columns.Add("id", typeof(string)); 
dt.Columns.Add("name", typeof(string)); 

foreach(var row in query2) 
{ 
    dt.Rows.Add(row); // ID field contains both ID and Name strings. Name field contains nothing 
} 
+1

Что происходит не так? Можете ли вы описать проблему более четко, вы получаете исключение? Что такое 'запрос'? –

ответ

0

Вы должны заполнить каждую ячейку в строке вручную:

foreach(var row in query2) 
{ 
    var newRow = dt.NewRow(); 
    newRow["id"]= row.id; 
    newRow["name"]= row.name; 
    dt.Rows.Add(newRow); 
} 
0

От MSDN:

DataRow newCustomersRow = dataSet1.Tables["Customers"].NewRow(); 

newCustomersRow["CustomerID"] = "ALFKI"; 
newCustomersRow["CompanyName"] = "Alfreds Futterkiste"; 

dataSet1.Tables["Customers"].Rows.Add(newCustomersRow); 

Это как добавить строку в DataTable

Так твое было бы как:

foreach(var row in query2) 
{ 
var newRow = dt.NewRow(); 
newRow["id"] = row.id; 
newRow["name"] = row.name; 
    dt.Rows.Add(newRow); // ID field contains both ID and Name strings. Name field contains nothing 
} 
0

Я бы избежать DataTable для этого метода и использовать ПОКО, Plain Old класс Object.

public class POCO 
{ 
    public string id { get; set; } 
    public string name { get; set; } 
} 

var query2 = from s in Tables[Table_Sec].AsEnumerable() 
      where query.Contains(s["sectype"]) 
      select new POCO { id = s["id"], name = s["name"] }; 

Преимущества POCO вы отделить данные от ассоциации с чем-то существующим и вместо того, чтобы отнести его к классу, который существует, чтобы служить только в качестве коллекции.

0

Вы не очень хорошо описали проблему. Однако вам не следует добавлять строки в разные DataTables, потому что вы обычно получаете исключение («Строка уже принадлежит другой таблице»).

Вы должны использовать строго типизированный метод расширения поля, чтобы исключить неправильное использование ReferenceEquals при выборе объекта. Вы можете использовать CopyToDataTable для создания нового DataTable из запроса Linq, когда он содержит IEnumerable<DataRow>.

Я хотел бы также использовать Enumerable.Join вместо query.Containsfor performance reasons:

var query2 = from secRow in Tables[Table_Sec].AsEnumerable() 
      join sectype in query on secRow.Field<string>("sectype") equals sectype 
      select secRow; 

DataTable dt = query2.CopyToDataTable(); 
1

Вы можете попробовать это, потому что конструктор DataRow позволяет передать объект массива

var result = from s in Tables[Table_Sec].AsEnumerable() 
      where query.Contains(s["sectype"]) 
      select new object[] 
      { 
       s["id"], 
       s["name" ] 
      }; 

DataTable dt = new DataTable(); 
dt.Columns.Add("id", typeof(string)); 
dt.Columns.Add("name", typeof(string)); 

foreach(var row in result) 
{ 
    dt.Rows.Add(row); 
} 

// EDIT:
Я бы не рекомендовал этот путь, потому что он сильно зависит от правильного порядка столбцов, и я даже не уверен, есть ли другие обстоятельства, как это может закончиться беспорядком =) Выберите один из других решений (по крайней мере для кодирования)