C#Winform(实体框架) - 将数据绑定DataGridView或BindingSource转换为DataTable

时间:2016-08-28 13:11:39

标签: c# winforms entity-framework datagridview datatable

我正在使用C#Winforms和Entity Framework,我的项目建模在此链接上:Databinding with WinForms

我的问题是如何将DataGridViewBindingSource转换为DataTable

我试过这段代码:

DataTable data = (DataTable)(DataGridView1.DataSource);

但是因错误而失败:

  

无法转换类型为#System; Windows.Forms.BindingSource'的对象输入' System.Data.DataTable'。

然后我尝试了这段代码:

BindingSource bs = (BindingSource)DataGridView1.DataSource;
DataTable dt = (DataTable)bs.DataSource;

但最终会出现另一个错误:

  

无法转换类型为#System; System.Data.Entity.Internal.DbLocalView`1 [Project1.Contexts.table1]'输入' System.Data.DataTable'。

尝试搜索其他类似问题和其他网站,但找不到将System.Data.Entity.Internal.DbLocalView转换为DataTable的方法。

修改

这是我的代码和要求。

要求:

我有2个表单,第1个表单的DataGridView名为enrollmedsDataGridView,DataBounded为enrollmedsBindingSourceenrollmedsBindingSource.DataSource设置为m3d.enrollmeds.Localm3d是我的上下文)。窗口包含ItemRemarks的文本框(每个项目的备注选项),Save按钮保存Add的列表和按钮,这将打开第二个表单以选择项目物品主列表。

要将第二个表单上的所选项目转移到第一个表单,我将DataGridView转换为DataTable,然后清除第一个表单的BindingSource并将所选项目重新添加到{ {1}}

我想要的是让第二种形式知道哪些项目已经被选中以便能够设置默认选择的项目(目前第二种形式默认是所有项目都未选中)

第一表格的代码 BindingSource

1st Form - EnrollMedicationFrm

(EnrollMedicationFrm)

第二表格代码 M3dEntities m3d = new M3dEntities(); enrollmeds _enrollmeds; EnrollMedSelectionFrm enrollselectfrm; public DataTable SelectedItems { get; set; } public string SelectedAdmNo { get; set; } private void EnrollMedicationFrm_Load(object sender, EventArgs e) { var _SelectedPKAdm = (from p in m3d.admission where p.admissionNo == SelectedAdmNo select p.PK_Admission).FirstOrDefault(); int _selectedAdmno = int.Parse(SelectedAdmNo); m3d.enrollmeds.Where(adm => adm.FK_Admission == _SelectedPKAdm).ToList(); this.enrollmedsBindingSource.DataSource = m3d.enrollmeds.Local; } private void AddBtn_Click(object sender, EventArgs e) { enrollselectfrm = new EnrollMedSelectionFrm(); var pxdetails = (from adm in m3d.admission join pxDC in m3d.datacenter on adm.FK_DC_Patient equals pxDC.PK_Datacenter where adm.admissionNo == SelectedAdmNo select new { adm, pxDC }).FirstOrDefault(); if (enrollselectfrm.ShowDialog() == DialogResult.OK) { if (SelectedItems == null) { enrollmedsBindingSource.Clear(); } else { enrollmedsBindingSource.Clear(); foreach (DataRow dr in SelectedItems.Rows) { _enrollmeds = new enrollmeds(); _enrollmeds.FK_DC_Patient = pxdetails.pxDC.PK_Datacenter; _enrollmeds.FK_DC_userAdd = mainfrm.PK_DC_UserLoggedIn; var svrDT = ((IObjectContextAdapter)m3d).ObjectContext.CreateQuery<DateTime>("CurrentDateTime() "); DateTime currdatetime = svrDT.AsEnumerable().First(); _enrollmeds.AddDateTime = currdatetime; _enrollmeds.FK_Admission = pxdetails.adm.PK_Admission; _enrollmeds.Qty = 0; int pkItems = int.Parse(dr.Field<string>("PK_Items").ToString()); var itemdtls = (from i in m3d.items where i.PK_Items == pkItems select i).FirstOrDefault(); _enrollmeds.FK_Items = pkItems; _enrollmeds.ItemRemarks = itemdtls.ItemRemarks; enrollmedsBindingSource.Add(_enrollmeds); } } } }

2nd Form - EnrollMedSelectionFrm

(EnrollMedSelectionFrm)

我对此流程有很多表单验证,但所有这些都有此问题:( 一旦这个问题得到解决,我认为其中所有或大部分都可以修复

请指导我如何解决这个问题,其他方法甚至解决方法都可以提供很大的帮助,非常感谢提前:)

1 个答案:

答案 0 :(得分:1)

使用实体框架时,您不需要使用DataTable。相反,您应该依赖List<T>DbSet<T>ObservableCollection<T>BindingList<T>等类。

让我们关注当前的要求:

  

我想要的是让第二种形式知道什么是物品   已经选定......

请考虑以下注意事项:

  • DataGridView绑定到List<T>时,每行的DataBoundItem属性的类型为T

  • 您可以致电Cast<DataGridViewRow>

  • 搜索Rows DataGridViewDataGridView集合

由于您使用CheckBoxColumn1检查某些行,因此您可以在网格中设置一个复选框列,并将其名称设置为private void selectButton_Click(object sender, EventArgs e) { this.dataGridView1.EndEdit(); var checkedItems = this.dataGridView1.Rows.Cast<DataGridViewRow>() .Where(x => (bool?)x.Cells["CheckBoxColumn1"].Value == true) .Select(x => x.DataBoundItem) .Cast<MyItem>().ToList(); //use checkedItems } 。然后在您的选择按钮中,您可以通过以下方式找到选中的项目:

MyItem

在上面的代码中,我认为match = [] 是您在网格中显示的列表项的类型。