2011-06-03 85 views
0

我创建winForm应用程序,在该Onbutton点击我从两个数据库的Mysql和Sqlite数据库收集数据表。 在将Linq查询转换为IEnumerable时,我正在执行Casting错误,以便将查询值提取到DataTable以在DataGrid视图中进行显示。铸造Linq IEnumerable <Datarow>

private void button1_Click(object sender, EventArgs e) 
{ 

    var obj = new table1TableAdapter(); //Mysql Table Adapter 
    var obj2 = new Table1TableAdapter(); // Sqlite Table Adapter 
    var ds = new DataSet(); 
    ds.Tables.Add(obj.GetData()); 
    ds.Tables.Add(obj2.GetData()); 
    var tab1 = ds.Tables[0]; 
    var tab2 = ds.Tables[1]; 
    var query = from o in tab1.AsEnumerable() 
       join od in tab2.AsEnumerable() 
       on o.Field<string>("Name") equals od.Field<string>("Name") 
       select new 
       { 
        Name = o.Field<string>("Name"), 
        Rollno = od.Field<Int64>("rollno"), 
        Book = o.Field<string>("Book") 
       }; 

    var q2 = (IEnumerable<DataRow>)query; //Unable to cast object of type <JoinIterator> 

    DataTable orderTable = q2.CopyToDataTable(); 
    dataGridView1.DataSource = orderTable; 
} 
+3

这不是一个DataRow,你不能神奇地把它变成'的DataRow ' – SLaks 2011-06-03 15:15:42

回答

6

看看你的代码,我会说,为什么要将它投射到IEnumerable<DataRow>?只需将查询绑定到您的GridView即可。

dataGridView1.DataSource = query.ToList(); 
+0

谢谢它有帮助 – 2011-06-03 15:37:10

4

这是因为您返回的查询对象与DataRow没有关系。 query将成为IEnumerable < SomeAnonymousType>。预计如何转换为DataRow

你需要改变你的声明作出的DataRow:

select new DataRow(/* Whatever Params */) { /* More Params */ }; 

然后,它本身的IEnumerable<DataRow>,不需要铸造。

1

一件事,你不会是能够转换为一个IEnumerable因为你查询本身不产生数据行

select new 
{ 
    Name = o.Field<string>("Name"), 
    Rollno = od.Field<Int64>("rollno"), 
    Book = o.Field<string>("Book") 
}; 

正在创建一个匿名类型。

你将不得不首先将它改变为DataRow,然后将其转换为IEnumerable。

3

由于您的查询正在创建IEnumerable,因此您无法将其转换为DataRow。我也不会建议使用选择新的DataRow(/ * Whatever Params /){/ More Params * /};因为这不会是一个真正的DataRow对象,并且是不好的做法。

我会这样处理它。即使这是一个小项目,Button_Click处理程序中也不应该有太多的代码。

首先,创建一个容器对象,称之为DTO或ViewModel。我建议后者。

public class BookViewModel 
{ 
    public string Name { get; set; } 

    public Int64 Rollno { get; set; } 

    public string Book { get; set; } 
} 

接下来,创建一个新的类,将执行您的SQL查询。这会将您的数据访问逻辑与表单逻辑分开。

public class BookService 
{ 
    public IList<BookViewModel> GetBookViewModel() 
    { 
     var obj = new table1TableAdapter(); //Mysql Table Adapter 
     var obj2 = new Table1TableAdapter(); // Sqlite Table Adapter 
     var ds = new DataSet(); 
     ds.Tables.Add(obj.GetData()); 
     ds.Tables.Add(obj2.GetData()); 
     var tab1 = ds.Tables[0]; 
     var tab2 = ds.Tables[1]; 
     var query = from o in tab1.AsEnumerable() 
        join od in tab2.AsEnumerable() 
        on o.Field<string>("Name") equals od.Field<string>("Name") 
        select new BookViewModel 
        { 
         Name = o.Field<string>("Name"), 
         Rollno = od.Field<Int64>("rollno"), 
         Book = o.Field<string>("Book") 
        }; 

     return query.ToList(); 
    } 

} 

最后,将列表绑定到您的显示器。

private void button1_Click(object sender, EventArgs e) 
    { 
     BookService bookService = new BookService(); 
     dataGridView1.DataSource = bookService.GetBookViewModel(); 
    } 

现在,当你回去修改你的代码,你将能够轻松地修改您的显示逻辑,并具有通过所有的混杂代码读出。

例子:

private void button1_Click(object sender, EventArgs e) 
     { 
      BookService bookService = new BookService(); 
      IList<BookViewModel> books = bookService.GetBookViewModel(); 
      if (books.Count == 0) 
      { 
         Label1.Text = "Sorry no books were found"; 
      } 
      dataGridView1.DataSource = books; 
     } 
0

我用下面的语句,这对我的作品

UC070_WizardStepFilesDataSet.AllDossierDetailResultsRow[] searchrows = 
         (from a in _wizardStepPreviewDataSet.AllDossierDetailResults 
         where a.WingsSetNbr == row.WingsSetNbr && !a.BookCode.StartsWith("V") 
         select a).ToArray<UC070_WizardStepFilesDataSet.AllDossierDetailResultsRow>();