天天看点

Entity Framework- Databinding with WinForms

文献参考

微软EF官方文档

实现IBindList接口

using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Entity;

namespace WinFormWithEF.Lib
{
    /// <summary>
    /// ObservableListSource
    /// </summary>
    public class ObservableListSource<T> : ObservableCollection<T>, IListSource
    where T : class
    {
        private IBindingList _bindingList;

        bool IListSource.ContainsListCollection { get { return false; } }

        IList IListSource.GetList()
        {
            return _bindingList ?? (_bindingList = this.ToBindingList());
        }
    }
}
           

定义模型

运用Code first,首先创建两个实体,Category实体和product实体,它们是一对多的关系。

namespace WinFormWithEF.Entity
{
    /// <summary>
    /// Category
    /// </summary>
    public class Category
    {
        private readonly ObservableListSource<Product> _products = new ObservableListSource<Product>();

        public int CategoryId { get; set; }
        public string Name { get; set; }

        public virtual ObservableListSource<Product> Products { get { return _products; } }
    }
}
           

Product实体:

namespace WinFormWithEF.Entity
{
    /// <summary>
    /// Product
    /// </summary>
    public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }

        public int CategoryId { get; set; }
        public virtual Category Category { get; set; } //navigation property
    }
}
           

除了定义实体类外,还需要定义一个继承于 DbContext的类,暴露

DbSet<TEntity>

属性。 DbSet属性使得上下文知道你想要什么类型包括在模型中。

这个 Dbset 实例管理运行时的对象,包括从数据库中获取数据填充到对象,更改跟踪,持久化数据到数据库。

添加一个 ProductContext 类:

using System.Data.Entity;

namespace WinFormWithEF.Entity
{
    /// <summary>
    /// ProductContext
    /// </summary>
    public class ProductContext : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }
    }
}
           

绑定对象到控件

vs2010中,选择数据->添加新数据源,如下图所示,选择对象,点击下一步,

Entity Framework- Databinding with WinForms

选择对应文件夹下的 Category,如下图所示,然后保存。

Entity Framework- Databinding with WinForms

绑定控件

将选择好的数据源拖拽到窗体的grid上,分别选择 Category对象上图,Product 对应下表格。为 保存添加相应handler,总的代码如下:

Entity Framework- Databinding with WinForms
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Entity;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WinFormWithEF.Entity;

namespace WinFormWithEF
{
    public partial class Form1 : Form
    {
        ProductContext _context;
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            _context = new ProductContext();

            // Call the Load method to get the data for the given DbSet 
            // from the database. 
            // The data is materialized as entities. The entities are managed by 
            // the DbContext instance. 
            _context.Categories.Load();

            // Bind the categoryBindingSource.DataSource to 
            // all the Unchanged, Modified and Added Category objects that 
            // are currently tracked by the DbContext.
            // Note that we need to call ToBindingList() on the 
            // ObservableCollection<TEntity> returned by
            // the DbSet.Local property to get the BindingList<T>
            // in order to facilitate two-way binding in WinForms.
            this.categoryBindingSource.DataSource =
                _context.Categories.Local.ToBindingList();
        }

        private void categoryBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            this.Validate();

            // Currently, the Entity Framework doesn’t mark the entities 
            // that are removed from a navigation property (in our example the Products)
            // as deleted in the context. 
            // The following code uses LINQ to Objects against the Local collection 
            // to find all products and marks any that do not have
            // a Category reference as deleted. 
            // The ToList call is required because otherwise 
            // the collection will be modified 
            // by the Remove call while it is being enumerated. 
            // In most other situations you can do LINQ to Objects directly 
            // against the Local property without using ToList first.
            foreach (var product in _context.Products.Local.ToList())
            {
                if (product.Category == null)
                {
                    _context.Products.Remove(product);
                }
            }

            // Save the changes to the database.
            this._context.SaveChanges();

            // Refresh the controls to show the values         
            // that were generated by the database.
            this.categoryDataGridView.Refresh();
            this.productsDataGridView.Refresh();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            this._context.Dispose();
        }

    }
}
           

点击保存。

查看数据库sql express

Entity Framework- Databinding with WinForms
Entity Framework- Databinding with WinForms
Entity Framework- Databinding with WinForms
Entity Framework- Databinding with WinForms