[英]Casting Linq to IEnumerable <Datarow>
我正在创建 winForm 应用程序,在那个 Onbutton 单击我从两个数据库 Mysql 和 Sqlite 数据库中收集数据表。 在将 Linq 查询转换为 IEnumerable 以将查询值提取到 DataTable 以在 DataGrid 视图中显示时出现转换错误。
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;
}
看着你的代码,我会说,为什么要把它转换成IEnumerable<DataRow>
呢? 只需简单地将查询绑定到您的 GridView。
dataGridView1.DataSource = query.ToList();
这是因为您返回的查询 object 与DataRow
无关。 query
将是一个 IEnumerable< SomeAnonymousType >。 预计如何转换为DataRow
?
您需要更改您的语句以创建 DataRow:
select new DataRow(/* Whatever Params */) { /* More Params */ };
然后它本身就是一个IEnumerable<DataRow>
并且不需要强制转换。
由于您的查询正在创建一个 IEnumerable,因此您无法将其转换为 DataRow。 我也不建议使用 select new DataRow(/* 不管参数/) { / More Params */ }; 因为这不是真正的 DataRow object 并且是不好的做法。
我会这样处理。 即使这是一个小项目,您的 Button_Click 处理程序中也不应该有那么多代码。
首先,创建一个容器 object,称之为 DTO 或 ViewModel。 我建议后者。
public class BookViewModel
{
public string Name { get; set; }
public Int64 Rollno { get; set; }
public string Book { get; set; }
}
接下来,创建一个新的 class 将执行您的 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();
}
现在,当您返回 go 以更改您的代码时,您将能够轻松地修改您的显示逻辑,而无需阅读所有混合代码。
例子:
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;
}
一方面,您将无法转换为 IEnumerable,因为您查询本身不会产生 DataRows
select new
{
Name = o.Field<string>("Name"),
Rollno = od.Field<Int64>("rollno"),
Book = o.Field<string>("Book")
};
正在创建一个匿名类型。
您必须先以某种方式将其更改为 DataRow,然后将其转换为 IEnumerable。
我正在使用以下语句,这对我有用
UC070_WizardStepFilesDataSet.AllDossierDetailResultsRow[] searchrows =
(from a in _wizardStepPreviewDataSet.AllDossierDetailResults
where a.WingsSetNbr == row.WingsSetNbr && !a.BookCode.StartsWith("V")
select a).ToArray<UC070_WizardStepFilesDataSet.AllDossierDetailResultsRow>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.