演练:创建 LINQ to SQL 类(O/R 设计器)

对象关系设计器(O/R 设计器)提供了一个可视化设计图面,用于创建和编辑基于数据库中对象的 LINQ to SQL 类(实体类)。通过使用 LINQ to SQL [LINQ to SQL],可以使用 LINQ 技术访问 SQL 数据库。有关更多信息,请参见LINQ(语言集成查询)

本演练提供了一些步骤,您必须执行这些步骤才能创建映射到 Northwind 数据库中 Customers 和 Orders 表的 LINQ to SQL 实体类并在 Windows 窗体中显示数据。除了用于显示表中数据的步骤之外,本演练还提供了用于将数据绑定到 LINQ 查询的步骤。最后,还提供了一些步骤,用于使用存储过程替换将更新从实体类发送到数据库的默认 LINQ to SQL 逻辑。

在本演练中,您将学习如何执行以下任务:

  • 将一个 LINQ to SQL 文件添加到项目。

  • 创建映射到数据库中相关表的新实体类。

  • 创建一个引用实体类的对象数据源。

  • 创建一个 Windows 窗体,该窗体包含绑定到实体类的控件。

  • 添加用于在实体类与数据库之间加载和保存数据的代码。

  • 构造一个简单的 LINQ 查询并在窗体中显示结果。

  • 将存储过程添加到 O/R 设计器中。

  • 配置一个实体类以使用存储过程执行插入、更新和删除。

先决条件

若要完成此演练,需要以下组件:

创建基于 Windows 的应用程序

由于要使用 LINQ to SQL 类并在 Windows 窗体中显示数据,因此本演练的第一步是创建一个新的 Windows 窗体应用程序。

创建新的 Windows 应用程序项目

  1. 从**“文件”**菜单创建一个新的项目。

  2. 将该项目命名为“ORDesignerWalkthrough”。

    注意注意

    由于 Visual Basic 项目和 C# 项目都支持 O/R 设计器,因此可以使用这两种语言之一来创建新项目。

  3. 单击**“Windows 窗体应用程序”模板,然后单击“确定”**。有关更多信息,请参见 开发客户端应用程序

    创建 ORDesignerWalkthrough 项目并将其添加到**“解决方案资源管理器”**中。

将 LINQ to SQL 类文件添加到该项目中(打开 O/R 设计器)

实体类将创建并存储在 LINQ to SQL 类文件(.dbml 文件)中。打开 .dbml 文件时会打开 O/R 设计器。通过在**“添加新项”对话框中选择“LINQ to SQL 类”**模板,将 .dbml 文件添加到项目中。

将一个 .dbml 文件添加到项目中

  1. 在**“项目”菜单上单击“添加新项”**。

  2. 单击**“LINQ to SQL 类”模板,然后在“名称”**框中键入 Northwind.dbml。

  3. 单击**“添加”**。

    这会将一个空的 LINQ to SQL 类文件 (Northwind.dbml) 添加到该项目中,并且会打开 O/R 设计器。

将新的 LINQ to SQL 文件添加到该项目中之后,将打开显示两个独立窗格的空设计图面。左边的窗格为实体窗格,可在其中显示和配置实体类。右边的窗格为方法窗格,该窗格显示添加到设计器的 DataContext 方法。如果方法窗格不可见,请右击实体窗格中的空白区域,然后单击**“显示方法窗格”。整个空图面表示一个可供配置的 DataContextDataContext 名称对应于为 .dbml 文件提供的名称。对于本演练,由于已将 LINQ to SQL 文件命名为 Northwind.dbml,因此 DataContext 被命名为 NorthwindDataContext。通过单击设计器上的任何空白区域并检查“属性”**窗口,可以对此进行验证。

注意注意

DataContext 类包含用于连接到数据库和操作数据库中数据(例如,执行插入、更新和删除)的方法和属性。有关更多信息,请参见 DataContext 方法(O/R 设计器)

创建 Customer 和 Order 实体类

通过将数据库表从**“服务器资源管理器”/“数据库资源管理器”**拖动到 O/R 设计器上,创建映射到这些表的 LINQ to SQL 类。结果将生成映射到数据库中表的 LINQ to SQL 实体类。

将 Customer 实体类添加到 O/R 设计器

  1. 在**“服务器资源管理器”/“数据库资源管理器”**中,查找 Northwind 示例数据库的 SQL Server 版本中的表。有关更多信息,请参见如何:创建到 Northwind 数据库的数据连接

  2. 将**“Customers”节点从“服务器资源管理器”/“数据库资源管理器”**拖动到 O/R 设计器图面上。

    将创建一个名为**“Customer”的实体类。该类具有与 Customers 表中的列相对应的属性。由于该实体类表示 Customers 表中的单个客户,因此将该类命名为“Customer”(而不是“Customers”**)。

    注意注意

    这种重命名行为称为“复数化”。可以在“选项”对话框 (Visual Studio) 中打开或关闭此行为。有关更多信息,请参见如何:打开和关闭复数形式(O/R 设计器)

  3. 将**“Orders”节点从“服务器资源管理器”/“数据库资源管理器”**拖动到 O/R 设计器图面上。

    将创建一个名为**“Order”的实体类,以及该实体类与“Customer”实体类之间的“Customer_Order”**关联(关系)。该类具有与 Orders 表中的列相对应的属性。

    注意注意

    由于该实体类表示单个订单,因此将该类命名为“Order”。父类(“Customer”)具有一个“Orders”属性,该属性表示该特定客户的订单集合。有关 LINQ to SQL 关联的更多信息,请参见如何:创建 LINQ to SQL 类之间的关联(关系)(O/R 设计器)

使用 Customer 实体类创建对象数据源

可以将实体类像具有公共属性的其他类一样用作对象数据源。可以将实体类添加到**“数据源”窗口中以及拖动到窗体上来创建数据绑定控件(绑定到对象公共属性中的值的控件)。通过运行“数据源配置向导”并在该向导中单击数据源的“对象”,可以将实体类添加到“数据源”**窗口。

在“数据源”窗口中添加 Customer 作为对象数据源

  1. 在**“生成”菜单上单击“生成 ORDesignerWalkthrough”**以生成该项目。

  2. 在**“数据”菜单上单击“显示数据源”**。

  3. 在**“数据源”窗口中,单击“添加新数据源”**。

  4. 单击**“选择数据源类型”页上的“对象”,然后单击“下一步”**。

  5. 展开**“ORDesignerWalkthrough”节点(带有项目名称的节点),然后找到并选择“Customer”**类。

    注意注意

    如果“Customer”类不可用,则退出向导,生成项目,然后重新运行向导。

  6. 单击**“完成”以创建数据源并将“Customer”实体类添加到“数据源”**窗口。

创建数据绑定控件以在 Windows 窗体中显示数据

通过将 LINQ to SQL 数据源项从**“数据源”**窗口拖动到 Windows 窗体上来创建绑定到实体类的控件。

添加绑定到实体类的控件

  1. 在“设计”视图中打开**“Form1”**。

  2. 将**“Customer”节点从“数据源”窗口拖动到“Form1”**上。

    注意注意

    若要显示“数据源”窗口,请单击“数据”菜单上的“显示数据源”

  3. 将**“Orders”节点从“数据源”窗口拖动到“Form1”上。将该节点放置在“CustomerDataGridView”**下。

  4. 在代码视图中打开**“Form1”**。

  5. 将下面的代码添加到该窗体中。这些代码对于该窗体是全局性的,位于任何特定方法之外,但位于 Form1 类内部:

    Private NorthwindDataContext1 As New NorthwindDataContext
    
    private NorthwindDataContext northwindDataContext1
        = new NorthwindDataContext();
    
  6. 为 Form_Load 事件创建一个事件处理程序,并将下面的代码添加到该处理程序中:

    CustomerBindingSource.DataSource = NorthwindDataContext1.Customers
    
    customerBindingSource.DataSource
        = northwindDataContext1.Customers;
    

测试应用程序

运行该应用程序。此时,窗体包含一个显示 Customers 表中数据的 DataGridView 和另一个显示所选客户的订单数据的 DataGridView

注意注意

请注意,保存按钮被禁用。(在下一节中将实现保存功能。)

测试应用程序

  1. 按 F5。

  2. 验证数据是否出现在网格中。

  3. 选择一个客户。

  4. 验证所显示的订单是否为所选客户的订单。

  5. 关闭窗体。(在**“调试”菜单上单击“停止调试”**。)

实现保存功能

如前所述,默认情况下未启用保存按钮,并且未实现保存功能。此外,在为对象数据源创建数据绑定控件时,不会自动将用于保存已更改数据的代码添加到窗体中。本节说明如何为 LINQ to SQL 对象启用保存按钮并实现保存功能。

实现保存功能

  1. 在“设计”视图中打开**“Form1”**。

  2. 选择**“CustomerBindingNavigator”**上的保存按钮。(该按钮标记有软盘图标。)

  3. 在**“属性”窗口中,将“Enabled”属性设置为“True”**。

  4. 双击保存按钮以创建一个事件处理程序并切换到代码编辑器。

  5. 将下面的代码添加到保存按钮事件处理程序中:

    Try
        NorthwindDataContext1.SubmitChanges()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
    
    try
    {
        northwindDataContext1.SubmitChanges();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    

测试应用程序

运行该应用程序。保存按钮应该已启用,并且保存数据的功能可用。

测试应用程序

  1. 按 F5。

  2. 在任意一个网格中修改一些数据。(将光标从网格中编辑过的行移开,以提交进程内更改。)

  3. 单击“保存”按钮将更改保存回数据库。

  4. 关闭窗体。

  5. 按 F5 并验证更改是否已保存(或查找数据库中的表来验证更改是否已保存)。

绑定到 LINQ 查询

除了将 CustomerBindingSource 绑定到 DataContext 以外,还可以直接绑定到 LINQ 查询。有关如何创建 LINQ 查询的更多信息,请参见 LINQ 查询简介 (C#)

将按钮和文本框添加到窗体中

若要了解如何将控件绑定到 LINQ 查询,可以将相应的控件添加到窗体中,使用这些控件输入查询参数,然后运行查询。

向窗体添加控件

  1. 在“设计”视图中打开**“Form1”**。

  2. 将一个**“TextBox”添加到该窗体中,然后将其“名称”属性设置为“CityTextBox”**。

  3. 将一个**“Button”**添加到该窗体中,并设置以下属性:

    • “名称”=“RunQueryButton”

    • “文本”=“运行查询”

数据绑定到 LINQ 查询

添加用于运行 LINQ 查询的代码。该查询使用键入到**“CityTextBox”**中的值作为查询参数。

绑定到 LINQ 查询

  • 双击**“RunQueryButton”**并将下面的代码添加到 RunQueryButton_click 事件处理程序:

    Dim CustomersQuery = From customers in NorthwindDataContext1.Customers _
        Where customers.City = CityTextBox.Text _
        Select customers
    
    CustomerBindingSource.DataSource = CustomersQuery
    
    var CustomersQuery = from customers in northwindDataContext1.Customers
                          where customers.City == CityTextBox.Text
                          select customers;
    
    customerBindingSource.DataSource = CustomersQuery;
    

测试应用程序

运行该应用程序。现在可以查询特定城市中的客户。

测试应用程序

  1. 按 F5。

  2. 在文本框中键入 London。

  3. 单击**“运行查询”**按钮。

  4. 验证是否仅显示其**“City”属性值为“London”**的客户。

重写用于执行更新(插入、更新和删除)的默认行为

默认情况下,由 LINQ to SQL 运行时提供用于执行更新的逻辑。该运行时基于 Select 语句(用于在实体类中填充数据)创建默认的 Insert、Update 和 Delete 语句。当不希望使用默认行为时,可以配置更新行为并指定特定的存储过程,以执行操作数据库中数据所必需的插入、更新和删除。在不生成默认行为时(例如,实体类映射到联接表时),也可以这样做。另外,在数据库要求通过存储过程访问表时,您可以重写默认的更新行为。

注意注意

本节要求可以使用 Northwind 数据库的“InsertCustomer”“UpdateCustomer”“DeleteCustomer”等附加存储过程。有关如何创建这些存储过程的详细信息,请参见演练:为 Northwind Customers 表创建更新存储过程

重写默认更新行为

  1. 在 O/R 设计器 中打开**“LINQ to SQL”文件。(在“解决方案资源管理器”中双击“Northwind.dbml”** 文件。)

  2. 在**“服务器资源管理器”/“数据库资源管理器”中展开 Northwind 数据库“存储过程”节点,然后找到“UpdateCustomers”**存储过程。

  3. 将**“UpdateCustomers”**存储过程拖动到 O/R 设计器中。

    **“UpdateCustomers”**存储过程将作为一个 DataContext 方法添加到方法窗格中。有关更多信息,请参见 DataContext 方法(O/R 设计器)

  4. 在 O/R 设计器中选择**“Customer”**实体类。

  5. 在**“属性”窗口中,选择要重写的命令(“Insert”“Update”“Delete”)。对于本示例,请选择“Update”**属性。

  6. 单击**“使用运行时”旁的省略号以打开“配置行为”**对话框。

  7. 选择**“自定义”**。

  8. 在**“自定义”列表中选择“UpdateCustomers”**方法。

  9. 检查**“方法参数”“类属性”列表,您会注意到,对于表中的某些列,有两个“方法参数”和两个“类属性”**。这样可以方便地跟踪更改并创建用于检查并发冲突的语句。

  10. 将原始方法参数(原始_ArgumentName)映射到原始属性(PropertyName(原始))。对于本演练,必须将**“Original_CustomerID”参数映射到“CustomerID (原始)”**属性。

    注意注意

    默认情况下,当名称匹配时,方法参数会映射到类属性。如果属性名称发生更改并且在表与实体类之间不再匹配,则在设计器无法确定正确的映射时,您可能必须选择等效的类属性进行映射。此外,如果方法参数没有用于进行映射的有效类属性,则可以将“类属性”值设置为“(无)”

  11. 单击**“确定”**。

测试应用程序

再次运行应用程序以验证**“UpdateCustomers”**存储过程是否能够正确更新数据库中的客户记录。

测试应用程序

  1. 按 F5。

  2. 在**“ALFKI”的网格中找到“ContactName”**列。

  3. 将姓名从**“Maria Anders”**更改为 Anders。

  4. 将光标从该行移开以提交更改。

  5. 单击“保存”按钮。

  6. 关闭窗体。

  7. 按 F5 再次运行应用程序,并验证是否仅有 Anders 显示在**“ALFKI”“ContactName”**列中。

后续步骤

根据应用程序要求的不同,您可能需要在创建 LINQ to SQL 实体类后执行几个步骤。您可以对此应用程序进行的增强包括:

请参阅

概念

O/R 设计器概述

操作的数据在Visual Studio中开发应用程序是新的2012年

其他资源

对象关系设计器(O/R 设计器)

LINQ to SQL [LINQ to SQL]

LINQ General Programming Guide

LINQ to ADO.NET

LINQ Documentation Roadmap

在 Visual Studio 中访问数据