65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Entity Framework 实现的主从视图

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (7投票s)

2016年7月22日

CPOL

3分钟阅读

viewsIcon

51279

downloadIcon

3864

在本文中,我将使用 Entity Framework 创建一个主从视图。

目录

引言

在本文中,我将讨论使用 Entity Framework 创建一个数据库连接的 WPF 应用程序。我创建了两个示例应用程序。 第一个示例 展示了如何使用 Entity Framework 创建一个主从视图。 这个 示例 应用程序 连接到SQL Server 2012 并从 Northwind 示例数据库中检索客户、订单和订单详细信息数据。然后,根据选定的客户和订单,将检索到的数据呈现给用户。 第二个示例应用程序使用一个自定义表来存储客户记录。 此应用程序允许您使用 Entity Framework 编辑、删除和创建新客户。这两个示例应用程序如下所示,源代码可以在本文顶部找到。

图 1:主从视图的 UI。

图 2:使用 Entity Framework 的简单 CRUD 应用程序。

背景

Entity Framework 允许您使用对象映射从您的 .net 应用程序与您的数据库进行通信。 使用这种方法,您可以访问数据库中的表,而无需编写单个 SQL 语句。此外,Entity Framework 允许您使用事务,以便多个数据库操作成功或失败。 在本文中,我编写了两个简单的应用程序来说明使用 Entity Framework 的强大功能。

主从视图

要将 ADO.NET 实体数据模型添加到您的应用程序中,您需要执行以下步骤。 右键单击您的项目,选择“添加新项” ->“ADO.NET 实体数据模型” ->“从数据库生成”。 接下来,选择一个数据库并测试连接。 在您按下“下一步”后,将检索数据库表,您需要选择要使用的表。 最后单击“完成”以导入数据模型。 如图所示,我导入了三个表(Customers、Orders 和 Order details)的数据模型。 

图 3:主从视图中使用的表。 

如上图所示,一个客户可以有零个或多个与其关联的订单。每个订单至少包含一个订单详细信息。 主从应用程序使用 MVVM 架构编写。MainView 由三个数据网格组成。 当 应用程序启动时,最上面的数据网格会填充客户对象。 当应用程序用户选择一个客户时,与该客户关联的订单将被检索并在订单数据网格中显示。 此外,当应用程序用户选择一个订单时,与该订单关联的订单详细信息 将被检索 并在产品数据网格中显示。 下面的代码片段显示了如何填充视图中的三个数据网格。

    public class MainWindowViewModel
    {
        private NorthwindEntities db = null;

        public MainWindowViewModel()
        {
            db = new NorthwindEntities();
            db.Configuration.LazyLoadingEnabled = false;
            db.Configuration.AutoDetectChangesEnabled = false;
            CustomersCollection = new ObservableCollection<Customers>(db.Customers);
            OrdersCollection = new ObservableCollection<Orders>();
            ProductCollection = new ObservableCollection<Order_Details>();
        }

        private ObservableCollection<Customers> customersCollection;
        public ObservableCollection<Customers> CustomersCollection
        {
            get
            {
                return customersCollection;
            }
            set
            {
                customersCollection = value;
                NotifyPropertyChanged();
            }
        }

        Customers selectedCustomers = null;
        public Customers SelectedCustomers
        {
            get { return selectedCustomers; }
            set
            {
                selectedCustomers = value;
                NotifyPropertyChanged();
                GetOrders(selectedCustomers.CustomerID);
                ProductCollection.Clear();
            }
        }

        private ObservableCollection<Orders> ordersCollection;
        public ObservableCollection<Orders> OrdersCollection
        {
            get
            {
                return ordersCollection;
            }
            set
            {
                ordersCollection = value;
                NotifyPropertyChanged();
            }
        }

        Orders selectedOrder = null;
        public Orders SelectedOrder
        {
            get { return selectedOrder; }
            set
            {
                selectedOrder = value;
                NotifyPropertyChanged();
                if (selectedOrder != null)
                {
                    GetOrderDetails(selectedOrder.OrderID);
                }
            }
        }

        private ObservableCollection<Order_Details> productCollection;
        public ObservableCollection<Order_Details> ProductCollection
        {
            get
            {
                return productCollection;
            }
            set
            {
                productCollection = value;
                NotifyPropertyChanged();
            }
        }

        private void GetOrders(object CustomerID)
        {
            var query = (from order in db.Orders
                         where order.CustomerID == CustomerID
                         select order).ToList();

            OrdersCollection.Clear();
            foreach (Orders order in query)
            {
                OrdersCollection.Add(order);
            }
        }

        private void GetOrderDetails(object OrderID)
        {
            int orderID = int.Parse(OrderID.ToString());
            var query = (from orderDetails in db.Order_Details
                         where orderDetails.OrderID == orderID
                         select orderDetails).ToList();

            ProductCollection.Clear();

            foreach (Order_Details order in query)
            {
                ProductCollection.Add(order);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

代码片段 1:用于填充 主从视图的代码。 

使用 Entity Framework 的简单 CRUD 应用程序

我创建了一个简单的 CRUD 应用程序来说明 Entity Framework 的强大功能。 用于存储应用程序数据的数据库表是使用下面显示的 SQL 语法创建的。

use [ExampleDatabase];

CREATE TABLE Customers  
(  
 id int IDENTITY(1,1),  
 FirstName varchar (50),
 LastName varchar (50),
 Gender varchar (10),
 SSN varchar (20),
 PhoneNumber varchar (20),
 Email varchar (255)
);

INSERT Customers (FirstName, LastName, Gender, SSN, PhoneNumber, Email)  
VALUES ('Arnold', 'Schwarzenegger', 'Male', '428-20-1786', '202-555-0256', 'Arnold.Schwarzenegger@gmail.com');  
  
INSERT Customers (FirstName, LastName, Gender, SSN, PhoneNumber, Email)  
VALUES ('Emma', 'Watson', 'Female', '230-58-8128', '202-555-0189', 'Emma.Watson@yahoo.com');  

INSERT Customers (FirstName, LastName, Gender, SSN, PhoneNumber, Email)  
VALUES ('Mila', 'Kunis', 'Female', '678-34-3456', '342-456-324', 'MilaKunis@outlook.com'); 

代码片段 2:用于创建示例数据的 SQL 代码。 

此外,我使用了一个通用存储库来访问数据库并执行 CRUD 操作。 通用存储库代码如下所示。

    public class GenericRepository<T> : IGenericRepository<T> where T : class
    {
        private ExampleDatabaseEntities db = null;
        private DbSet<T> table = null;

        public GenericRepository()
        {
            this.db = new ExampleDatabaseEntities();
            table = db.Set<T>();
        }

        public GenericRepository(ExampleDatabaseEntities db)
        {
            this.db = db;
            table = db.Set<T>();
        }

        public IEnumerable<T> SelectAll()
        {
            return table.ToList();
        }

        public T SelectByID(object id)
        {
            return table.Find(id);
        }

        public void Insert(T obj)
        {
            table.Add(obj);
        }

        public void Update(T obj)
        {
            table.Attach(obj);
            db.Entry(obj).State = EntityState.Modified;
        }

        public void Delete(object id)
        {
            T existing = table.Find(id);
            table.Remove(existing);
        }

        public void Save()
        {
            db.SaveChanges();
        }
    }

代码片段 3:支持 CRUD 操作的通用存储库。 

CRUD 操作是硬编码的。 正如您在下面的代码中看到的,由于有了 Entity Framework,无需使用任何 SQL 语句即可执行 CRUD 操作。 

private IGenericRepository<Customers> repository = null;
public MainWindow()
{
    InitializeComponent();
    this.repository = new GenericRepository<Customers>();
    CustomersCollection = new ObservableCollection<Customers>(this.repository.SelectAll());
    this.DataContext = this;
}

private void InsertHandler(object sender, RoutedEventArgs e)
{
    Customers aCustomer = new Customers() 
    {
        FirstName = "Mohamed",
        LastName = "Kalmoua",
        PhoneNumber="0654654098",
        Email ="Mohamed.Kalmoua@gmail.com"
    }; 
    repository.Insert(aCustomer);
    repository.Save();
    UpdateCollection();
}

private void DeleteHandler(object sender, RoutedEventArgs e)
{
    repository.Delete(SelectedCustomer.id);
    repository.Save();
    UpdateCollection();
}

private void UpdateHandler(object sender, RoutedEventArgs e)
{
    SelectedCustomer.FirstName = SelectedCustomer.FirstName + "_Updated";
    SelectedCustomer.LastName = SelectedCustomer.LastName + "_Updated";
    repository.Update(SelectedCustomer);
    repository.Save();
    UpdateCollection();
}

private void ReadHandler(object sender, RoutedEventArgs e)
{
    string customer = SelectedCustomer.FirstName + Environment.NewLine +
        SelectedCustomer.LastName + Environment.NewLine +
        SelectedCustomer.SSN + Environment.NewLine;

    System.Windows.MessageBox.Show(customer);
}

代码片段 4:使用通用存储库。 

关注点

使用 Entity Framework 时,某些设置(例如 lazyloading、AutoDetectChangesEnabled) 可能会对您的应用程序的性能产生负面影响。

参考文献

历史

  • 2016 年 7 月 23 日:版本 1.0.0.0 - 发布文章
© . All rights reserved.