繁体   English   中英

如何使用Entity Framework以DataGridView可编辑和上下文跟踪更改的方式过滤数据?

[英]How to filter data using Entity Framework in a way that DataGridView be editable and context track changes?

我正在使用C#Windows Form Application使用以下代码使用Entity Framework(EFWinForms)从sql server数据库表填充数据:

MyEntityDataModel db = new MyEntityDataModel();
MyEDS = new EntityDataSource();
MyEDS.DbContext = db;
MyDataGridView.DataSource = MyEDS;
MyDataGridView.DataMember = "MyTable";

它工作正常。 用户编辑时,添加数据; 可以使用以下代码保存数据:

MyEDS.SaveChanges();

我想要一种通过实体数据源过滤这些数据的方法,以便MyDataGridView保持可编辑状态,用户在过滤数据中完成的任何更新仍然可以保存回数据库。 注意:当使用linq to entity过滤数据时,它工作得很好,但它只是填充了用户无法再次编辑或更新的数据快照。

如果要在连接模式下使用Windows窗体中的实体框架,如果要保持DataGridView可编辑,即使应用了过滤器,也应该考虑一些重点。

使用DbContext的单个实例

使用DbContext的单个实例。 如果在保存更改时创建新实例,则新实例无法看到您在其他实例上所做的任何更改。 所以在表单级别声明它:

TestDBEntities db = new TestDBEntities();

加载数据 - 绑定到实体的本地存储

在连接模式下使用实体时,使用db.Products.Load()db.Products.ToList()加载数据。

BindingSource绑定到db.Products.Local.ToBindingList() 因此,如果您在绑定源中添加或删除项目,更改跟踪器会检测更改并为您添加和删除项目。

要查看ToBindingList扩展方法,请using System.Data.Entity;添加using System.Data.Entity;

如果在DataGridView启用了添加,则关闭代理创建以防止过滤时出现异常。

db.Configuration.ProxyCreationEnabled = false;
db.Products.Load(); 
this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();

使用Linq过滤数据

要过滤数据,请使用linq。 当底层列表是BindingList<T>时,您不能使用BindingSource Filter属性; 只有实现IBindingListView接口的底层列表才支持过滤。

要应用过滤,请使用linq。 例如:

var filteredData = db.Products.Local.ToBindingList()
    .Where(x => x.Name.Contains(this.FilterTextBox.Text));
this.productsBindingSource.DataSource = filteredData.Count() > 0 ?
    filteredData : filteredData.ToArray();

删除过滤器

要删除过滤器,只需将绑定源的数据源再次设置为实体的本地存储。 这样,当您删除过滤器时,添加和删除将起作用。

this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();

添加/删除/编辑

添加仅适用于未过滤模式。 要让用户添加实体,请删除过滤器。

编辑将在过滤或未过滤模式下工作。

删除在过滤或未过滤模式下工作。 但是如果在过滤模式下使用BindingNavigator ,则不能依赖其删除按钮。 要使其适用于过滤模式和非过滤模式,应将BindingNavigator DeleteItem属性设置为None并处理其删除项单击事件并编写您自己的代码:

if (productsBindingSource.Current != null)
{
    var current = (Product)this.productsBindingSource.Current;
    this.productsBindingSource.RemoveCurrent();
    if (!string.IsNullOrEmpty(this.FilterTextBox.Text))
        db.Products.Local.Remove(current);
}

处理或关闭表单时处理DbContext

对于真实世界的应用程序,请考虑将DbContext处理为处理或关闭表单:

db.Dispose();

示例代码

下面是一个示例代码,其中包含我上面描述的内容。

using System.Data.Entity;
SampleDbEntities db = new SampleDbEntities();
private void Form1_Load(object sender, EventArgs e)
{
    db.Configuration.ProxyCreationEnabled = false;
    db.Products.Load();
    this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();
}
private void FilterButton_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(this.FilterTextBox.Text))
    {
        this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();
    }
    else
    {
        var filteredData = db.Products.Local.ToBindingList()
            .Where(x => x.Name.Contains(this.FilterTextBox.Text));
        this.productsBindingSource.DataSource = filteredData.Count() > 0 ?
            filteredData : filteredData.ToArray();
    }
}
private void productBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
    this.Validate();
    productsBindingSource.EndEdit();
    db.SaveChanges();
}
private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
{
    if (productsBindingSource.Current != null)
    {
        var current = (Product)this.productsBindingSource.Current;
        this.productsBindingSource.RemoveCurrent();
        if (!string.IsNullOrEmpty(this.FilterTextBox.Text))
            db.Products.Local.Remove(current);
    }
}

虽然我不确定您的可能用途,但我通常在绑定源上使用filter属性来选择某些记录而不放弃更新数据库的能力。 像这样的东西:

        // Grab search string from SearchBox
        string strSearch = Convert.ToString(RichSearchBox.Text);

        // Apply Filter to BindingSource
        tblContactsBindingSource.Filter = "FileAs LIKE '*" + strSearch + "*'";

然后使用Binding Source作为数据网格视图的数据源:

        // Bind DataGridView to BindingSource
        recipientGridView.DataSource = tblContactsBindingSource;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM