演练:创建 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 设计器中。
配置一个实体类以使用存储过程执行插入、更新和删除。
先决条件
若要完成此演练,需要以下组件:
访问 Northwind 示例数据库的 SQL Server 版本。有关更多信息,请参见如何:安装示例数据库。
Northwind 数据库的**“UpdateCustomer”**存储过程。有关更多信息,请参见演练:为 Northwind Customers 表创建更新存储过程。
创建基于 Windows 的应用程序
由于要使用 LINQ to SQL 类并在 Windows 窗体中显示数据,因此本演练的第一步是创建一个新的 Windows 窗体应用程序。
创建新的 Windows 应用程序项目
从**“文件”**菜单创建一个新的项目。
将该项目命名为“ORDesignerWalkthrough”。
备注
由于 Visual Basic 项目和 C# 项目都支持 O/R 设计器,因此可以使用这两种语言之一来创建新项目。
单击**“Windows 窗体应用程序”模板,然后单击“确定”**。有关更多信息,请参见 开发客户端应用程序。
创建 ORDesignerWalkthrough 项目并将其添加到**“解决方案资源管理器”**中。
将 LINQ to SQL 类文件添加到该项目中(打开 O/R 设计器)
实体类将创建并存储在 LINQ to SQL 类文件(.dbml 文件)中。打开 .dbml 文件时会打开 O/R 设计器。通过在**“添加新项”对话框中选择“LINQ to SQL 类”**模板,将 .dbml 文件添加到项目中。
将一个 .dbml 文件添加到项目中
在**“项目”菜单上单击“添加新项”**。
单击**“LINQ to SQL 类”模板,然后在“名称”**框中键入 Northwind.dbml。
单击**“添加”**。
这会将一个空的 LINQ to SQL 类文件 (Northwind.dbml) 添加到该项目中,并且会打开 O/R 设计器。
将新的 LINQ to SQL 文件添加到该项目中之后,将打开显示两个独立窗格的空设计图面。左边的窗格为实体窗格,可在其中显示和配置实体类。右边的窗格为方法窗格,该窗格显示添加到设计器的 DataContext 方法。如果方法窗格不可见,请右击实体窗格中的空白区域,然后单击**“显示方法窗格”。整个空图面表示一个可供配置的 DataContext。DataContext 名称对应于为 .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 设计器
在**“服务器资源管理器”/“数据库资源管理器”**中,查找 Northwind 示例数据库的 SQL Server 版本中的表。有关更多信息,请参见如何:创建到 Northwind 数据库的数据连接。
将**“Customers”节点从“服务器资源管理器”/“数据库资源管理器”**拖动到 O/R 设计器图面上。
将创建一个名为**“Customer”的实体类。该类具有与 Customers 表中的列相对应的属性。由于该实体类表示 Customers 表中的单个客户,因此将该类命名为“Customer”(而不是“Customers”**)。
备注
这种重命名行为称为“复数化”。可以在“选项”对话框 (Visual Studio) 中打开或关闭此行为。有关更多信息,请参见如何:打开和关闭复数形式(O/R 设计器)。
将**“Orders”节点从“服务器资源管理器”/“数据库资源管理器”**拖动到 O/R 设计器图面上。
将创建一个名为**“Order”的实体类,以及该实体类与“Customer”实体类之间的“Customer_Order”**关联(关系)。该类具有与 Orders 表中的列相对应的属性。
备注
由于该实体类表示单个订单,因此将该类命名为“Order”。父类(“Customer”)具有一个“Orders”属性,该属性表示该特定客户的订单集合。有关 LINQ to SQL 关联的更多信息,请参见如何:创建 LINQ to SQL 类之间的关联(关系)(O/R 设计器)。
使用 Customer 实体类创建对象数据源
可以将实体类像具有公共属性的其他类一样用作对象数据源。可以将实体类添加到**“数据源”窗口中以及拖动到窗体上来创建数据绑定控件(绑定到对象公共属性中的值的控件)。通过运行“数据源配置向导”并在该向导中单击数据源的“对象”,可以将实体类添加到“数据源”**窗口。
在“数据源”窗口中添加 Customer 作为对象数据源
在**“生成”菜单上单击“生成 ORDesignerWalkthrough”**以生成该项目。
在**“数据”菜单上单击“显示数据源”**。
在**“数据源”窗口中,单击“添加新数据源”**。
单击**“选择数据源类型”页上的“对象”,然后单击“下一步”**。
展开**“ORDesignerWalkthrough”节点(带有项目名称的节点),然后找到并选择“Customer”**类。
备注
如果“Customer”类不可用,则退出向导,生成项目,然后重新运行向导。
单击**“完成”以创建数据源并将“Customer”实体类添加到“数据源”**窗口。
创建数据绑定控件以在 Windows 窗体中显示数据
通过将 LINQ to SQL 数据源项从**“数据源”**窗口拖动到 Windows 窗体上来创建绑定到实体类的控件。
添加绑定到实体类的控件
在“设计”视图中打开**“Form1”**。
将**“Customer”节点从“数据源”窗口拖动到“Form1”**上。
备注
若要显示“数据源”窗口,请单击“数据”菜单上的“显示数据源”。
将**“Orders”节点从“数据源”窗口拖动到“Form1”上。将该节点放置在“CustomerDataGridView”**下。
在代码视图中打开**“Form1”**。
将下面的代码添加到该窗体中。这些代码对于该窗体是全局性的,位于任何特定方法之外,但位于 Form1 类内部:
Private NorthwindDataContext1 As New NorthwindDataContext
private NorthwindDataContext northwindDataContext1 = new NorthwindDataContext();
为 Form_Load 事件创建一个事件处理程序,并将下面的代码添加到该处理程序中:
CustomerBindingSource.DataSource = NorthwindDataContext1.Customers
customerBindingSource.DataSource = northwindDataContext1.Customers;
测试应用程序
运行该应用程序。此时,窗体包含一个显示 Customers 表中数据的 DataGridView 和另一个显示所选客户的订单数据的 DataGridView。
备注
请注意,保存按钮被禁用。(在下一节中将实现保存功能。)
测试应用程序
按 F5。
验证数据是否出现在网格中。
选择一个客户。
验证所显示的订单是否为所选客户的订单。
关闭窗体。(在**“调试”菜单上单击“停止调试”**。)
实现保存功能
如前所述,默认情况下未启用保存按钮,并且未实现保存功能。此外,在为对象数据源创建数据绑定控件时,不会自动将用于保存已更改数据的代码添加到窗体中。本节说明如何为 LINQ to SQL 对象启用保存按钮并实现保存功能。
实现保存功能
在“设计”视图中打开**“Form1”**。
选择**“CustomerBindingNavigator”**上的保存按钮。(该按钮标记有软盘图标。)
在**“属性”窗口中,将“Enabled”属性设置为“True”**。
双击保存按钮以创建一个事件处理程序并切换到代码编辑器。
将下面的代码添加到保存按钮事件处理程序中:
Try NorthwindDataContext1.SubmitChanges() Catch ex As Exception MessageBox.Show(ex.Message) End Try
try { northwindDataContext1.SubmitChanges(); } catch (Exception ex) { MessageBox.Show(ex.Message); }
测试应用程序
运行该应用程序。保存按钮应该已启用,并且保存数据的功能可用。
测试应用程序
按 F5。
在任意一个网格中修改一些数据。(将光标从网格中编辑过的行移开,以提交进程内更改。)
单击“保存”按钮将更改保存回数据库。
关闭窗体。
按 F5 并验证更改是否已保存(或查找数据库中的表来验证更改是否已保存)。
绑定到 LINQ 查询
除了将 CustomerBindingSource 绑定到 DataContext 以外,还可以直接绑定到 LINQ 查询。有关如何创建 LINQ 查询的更多信息,请参见 LINQ 查询简介 (C#)。
将按钮和文本框添加到窗体中
若要了解如何将控件绑定到 LINQ 查询,可以将相应的控件添加到窗体中,使用这些控件输入查询参数,然后运行查询。
向窗体添加控件
在“设计”视图中打开**“Form1”**。
将一个**“TextBox”添加到该窗体中,然后将其“名称”属性设置为“CityTextBox”**。
将一个**“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;
测试应用程序
运行该应用程序。现在可以查询特定城市中的客户。
测试应用程序
按 F5。
在文本框中键入 London。
单击**“运行查询”**按钮。
验证是否仅显示其**“City”属性值为“London”**的客户。
重写用于执行更新(插入、更新和删除)的默认行为
默认情况下,由 LINQ to SQL 运行时提供用于执行更新的逻辑。该运行时基于 Select 语句(用于在实体类中填充数据)创建默认的 Insert、Update 和 Delete 语句。当不希望使用默认行为时,可以配置更新行为并指定特定的存储过程,以执行操作数据库中数据所必需的插入、更新和删除。在不生成默认行为时(例如,实体类映射到联接表时),也可以这样做。另外,在数据库要求通过存储过程访问表时,您可以重写默认的更新行为。
备注
本节要求可以使用 Northwind 数据库的“InsertCustomer”、“UpdateCustomer”和“DeleteCustomer”等附加存储过程。有关如何创建这些存储过程的详细信息,请参见演练:为 Northwind Customers 表创建更新存储过程。
重写默认更新行为
在 O/R 设计器 中打开**“LINQ to SQL”文件。(在“解决方案资源管理器”中双击“Northwind.dbml”** 文件。)
在**“服务器资源管理器”/“数据库资源管理器”中展开 Northwind 数据库“存储过程”节点,然后找到“UpdateCustomers”**存储过程。
将**“UpdateCustomers”**存储过程拖动到 O/R 设计器中。
**“UpdateCustomers”**存储过程将作为一个 DataContext 方法添加到方法窗格中。有关更多信息,请参见 DataContext 方法(O/R 设计器)。
在 O/R 设计器中选择**“Customer”**实体类。
在**“属性”窗口中,选择要重写的命令(“Insert”、“Update”或“Delete”)。对于本示例,请选择“Update”**属性。
单击**“使用运行时”旁的省略号以打开“配置行为”**对话框。
选择**“自定义”**。
在**“自定义”列表中选择“UpdateCustomers”**方法。
检查**“方法参数”和“类属性”列表,您会注意到,对于表中的某些列,有两个“方法参数”和两个“类属性”**。这样可以方便地跟踪更改并创建用于检查并发冲突的语句。
将原始方法参数(原始_ArgumentName)映射到原始属性(PropertyName(原始))。对于本演练,必须将**“Original_CustomerID”参数映射到“CustomerID (原始)”**属性。
备注
默认情况下,当名称匹配时,方法参数会映射到类属性。如果属性名称发生更改并且在表与实体类之间不再匹配,则在设计器无法确定正确的映射时,您可能必须选择等效的类属性进行映射。此外,如果方法参数没有用于进行映射的有效类属性,则可以将“类属性”值设置为“(无)”。
单击**“确定”**。
测试应用程序
再次运行应用程序以验证**“UpdateCustomers”**存储过程是否能够正确更新数据库中的客户记录。
测试应用程序
按 F5。
在**“ALFKI”的网格中找到“ContactName”**列。
将姓名从**“Maria Anders”**更改为 Anders。
将光标从该行移开以提交更改。
单击“保存”按钮。
关闭窗体。
按 F5 再次运行应用程序,并验证是否仅有 Anders 显示在**“ALFKI”的“ContactName”**列中。
后续步骤
根据应用程序要求的不同,您可能需要在创建 LINQ to SQL 实体类后执行几个步骤。您可以对此应用程序进行的增强包括:
添加更多存储过程以用于 Insert 和 Delete 命令。有关更多信息,请参见如何:分配存储过程以执行更新、插入和删除(O/R 设计器)。
构造各种 LINQ 查询以返回经过筛选的数据。有关更多信息,请参见如何:查询信息。
请参阅
概念
操作的数据在Visual Studio中开发应用程序是新的2012年
其他资源
LINQ General Programming Guide
LINQ Documentation Roadmap