C#Winform(实体框架) - 将数据绑定DataGridView或BindingSource转换为DataTable [英] C# Winform (Entity Framework) - cast databound DataGridView or BindingSource to DataTable

查看:3617
本文介绍了C#Winform(实体框架) - 将数据绑定DataGridView或BindingSource转换为DataTable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#Winforms和Entity Framework,我的项目是建立在这个链接上的:

  M3dEn tities m3d = new M3dEntities(); 
enrollmeds _enrollmeds;
EnrollMedSelectionFrm enrollselectfrm;
public DataTable SelectedItems {get;组; }
public string SelectedAdmNo {get;组; }

private void EnrollMedicationFrm_Load(object sender,EventArgs e)
{
var _SelectedPKAdm =(from p in m3d.admission
其中p.admissionNo == SelectedAdmNo
选择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
选择新
{
adm,
pxDC
})。FirstOrDefault();

if(enrollselectfrm.ShowDialog()== DialogResult.OK)
{
if(SelectedItems == null)
{
enrollmedsBindingSource.Clear );
}
else
{
enrollmedsBindingSource.Clear();

foreach(SelectedItems.Rows中的DataRow dr)
{
_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 =(从我在m3d.items
其中i.PK_Items == pkItems
选择i).FirstOrDefault();

_enrollmeds.FK_Items = pkItems;
_enrollmeds.ItemRemarks = itemdtls.ItemRemarks;

enrollmedsBindingSource.Add(_enrollmeds);
}
}
}
}

em>第二个表格的代码 (EnrollMedSelectionFrm)



  M3dEntities m3d = new M3dEntities(); 
private void EnrollMedSelectionFrm_Load(object sender,EventArgs e)
{
var items =从我在m3d.items
其中i.ItemGroup ==Medicine
select新
{
i.PK_Items,
i.ItemID,
i.ItemDesc,
i.GenericName
};

if(items!= null)
{
DataTable dt = new DataTable();
foreach(ItemSelectionDataGridView.Columns中的DataGridViewColumn col)
{
dt.Columns.Add(col.Name);
col.DataPropertyName = col.Name;
};
foreach(项目中的var元素)
{
var row = dt.NewRow();
row [PK_Items] = element.PK_Items;
row [ItemID] = element.ItemID;
row [ItemDesc] = element.ItemDesc;
row [GenericName] = element.GenericName;
dt.Rows.Add(row);
}
ItemSelectionDataGridView.DataSource = dt;
}


private void SelectBtn_Click(object sender,EventArgs e)
{
EnrollMedicationFrm enrollfrm =(EnrollMedicationFrm)Application.OpenForms [EnrollMedicationFrm ];
DataTable dt = new DataTable();
dt =(DataTable)ItemSelectionDataGridView.DataSource;
DataRow [] result = dt.Select(SelectedChkBox = 1);

if(result.Count()< 1)
{
enrollfrm.SelectedItems = null;
}
else
{
enrollfrm.SelectedItems = result.CopyToDataTable();
}

this.DialogResult = DialogResult.OK;
}

我有这个流程的许多表单验证,但都有这个问题(
一旦这个问题解决了,我认为所有或大部分都可以修复



请指导我如何解决这个问题,其他方法或即使是一个解决方法可能是一个很大的帮助,非常感谢提前:)

解决方案

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



目前的要求:


我想要的是让第二种形式知道哪些项目是
已经选择的方法


请考虑以下注意事项:





由于您正在使用 DataGridView 来检查某些行,盒子列,并将其名称设置为 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)
。选择(x => x.DataBoundItem)
.Cast< MyItem>()。ToList();

//使用checkedItems
}

在上面的代码中假设 MyItem 是您在网格中显示的列表项的类型。


I am working with C# Winforms and Entity Framework, my project is modeled on this link: Databinding with WinForms

My question is how can I convert a DataGridView or a BindingSource to a DataTable?

I tried this code:

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

but that failed with an error:

Unable to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Data.DataTable'.

Then I tried the this code instead:

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

but this ends up with another error:

Unable to cast object of type 'System.Data.Entity.Internal.DbLocalView`1[Project1.Contexts.table1]' to type 'System.Data.DataTable'.

Tried to search other similar questions and on other sites but cannot found a way to convert System.Data.Entity.Internal.DbLocalView to DataTable.

Edit:

Here's my code and requirements.

Requirements:

I have 2 forms, 1st form has DataGridView named enrollmedsDataGridView which DataBounded to enrollmedsBindingSource. enrollmedsBindingSource.DataSource is set to m3d.enrollmeds.Local (m3d is my context). Window has textbox for the ItemRemarks(remarks per item selected), a button for Save to save the list and button for Add which will open the 2nd form for the selection of items on the Item Masterlist.

To transfer the selected items on the 2nd form to 1st form, I cast the DataGridView to DataTable then clear the BindingSource of 1st form and Re-Add the items selected to BindingSource

What I want is to have a way for the 2nd form to know what items are already selected to be able to set the items selected by default (currently 2nd form default is all items are unchecked)

Codes for 1st Form (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);
                }
            }
        }
    }

Codes for 2nd Form (EnrollMedSelectionFrm):

    M3dEntities m3d = new M3dEntities();
    private void EnrollMedSelectionFrm_Load(object sender, EventArgs e)
    {
        var items = from i in m3d.items
                    where i.ItemGroup == "Medicine"
                    select new
                    {
                        i.PK_Items,
                        i.ItemID,
                        i.ItemDesc,
                        i.GenericName
                    };

        if (items != null)
        {
            DataTable dt = new DataTable();
            foreach (DataGridViewColumn col in ItemSelectionDataGridView.Columns)
            {
                dt.Columns.Add(col.Name);
                col.DataPropertyName = col.Name;
            };
            foreach (var element in items)
            {
                var row = dt.NewRow();
                row["PK_Items"] = element.PK_Items;
                row["ItemID"] = element.ItemID;
                row["ItemDesc"] = element.ItemDesc;
                row["GenericName"] = element.GenericName;
                dt.Rows.Add(row);
            }
            ItemSelectionDataGridView.DataSource = dt;
        }
    }

    private void SelectBtn_Click(object sender, EventArgs e)
    {
        EnrollMedicationFrm enrollfrm = (EnrollMedicationFrm)Application.OpenForms["EnrollMedicationFrm"];
        DataTable dt = new DataTable();
        dt = (DataTable)ItemSelectionDataGridView.DataSource;
        DataRow[] result = dt.Select("SelectedChkBox = 1");

        if (result.Count() < 1)
        {
            enrollfrm.SelectedItems = null;
        }
        else
        {
            enrollfrm.SelectedItems = result.CopyToDataTable();
        }

        this.DialogResult = DialogResult.OK;
    }

I have many form validations with this flow, but all of them has this issue :( Once this issue is fixed i think all or most of them can be fixed too

Please guide me on how to solve this problem, other approach or even a workaround could be a great help, Thanks very much in advance :)

解决方案

When using Entity Framework you don't need to use DataTable. Instead you should rely on classes like List<T>, DbSet<T>, ObservableCollection<T>, BindingList<T> and so on.

Let's focus on current requirement:

What I want is to have a way for the 2nd form to know what items are already selected...

Consider these notes:

  • When you bind a DataGridView to a List<T>, the DataBoundItem property of each row is of type T.

  • You can search on a Rows collection of DataGridView by calling Cast<DataGridViewRow>

Since you are using a DataGridView to check some rows, you can simply have a check-box column in grid and set its name to CheckBoxColumn1 for example. Then in your select button, you can find checked items this way:

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 
}

In above code I supposed MyItem is type of list items which you are showing in grid.

这篇关于C#Winform(实体框架) - 将数据绑定DataGridView或BindingSource转换为DataTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆