LINQ






2.43/5 (4投票s)
Linq_Part1
引言
语言集成查询(LINQ)改变了您编写数据驱动应用程序的方式。以前,开发人员需要以不同的方式思考和编码来访问 SQL Server 等不同的数据存储。新的基于 LINQ 的编程可以消除开发此类应用程序时涉及的麻烦。在这个多部分系列中,我将解释如何在 ASP.NET 应用程序中使用 LINQ 功能。
使用代码
1- 为要编辑的表创建一个实体类。
程序集和命名空间
在此示例中,您将使用 LINQ to SQL 功能,因此您需要在网站中引用 System.Data.LINQ 程序集。此程序集提供了两个重要的命名空间System.Data.Linq
System.Data.Linq.Mapping
前者命名空间提供了允许您与数据库交互的类,而后者命名空间包含用于生成表示表的实体类的类和属性。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Linq.Mapping; ////// This class is used to deal with users table. /// [Table(Name = "users")] public class users { [Column(Name = "ID",IsDbGenerated=true,IsPrimaryKey=true)] public int ID { get; set; } [Column(Name = "UserName", DbType = "nvarchar(50)")] public string UserName { get; set; } [Column(Name = "Password", DbType = "nvarchar(50)")] public string Password { get; set; } public users() { } }
公共类 users 包含三个公共属性:ID、UserName 和 Password。使这个类特别的是 [Table] 和 [Column] 属性。[Table] 属性标记在 users 类上,表示底层类代表关系型数据库管理系统的表。 [Table] 属性的 Name 属性指定数据库表的名称。如果您的类名和表名相同,您可以完全省略 Name 属性。属性级别的 [Column] 属性指定底层属性是表列。[Column] 属性有几个属性。一些重要的属性列在下面
Name:表列的名称
DbType:表列的数据类型(不是 .NET 数据类型!)
IsPrimaryKey:列是否代表表的主键
IsDbGenerated:列的值是否由关系型数据库管理系统自动生成(例如,标识列)
CanBeNull:列是否可以为 null
Storage:存储列数据的类字段的名称
请注意,在我们的示例中,ID 被标记为 IsDbGenerated 和 IsPrimaryKey 属性。另外,请注意 Name 和 DbType 属性的使用方式。
这样我们的 users 类就完成了。我们只使用了 users 表中的三个列。您可以根据需要添加额外的列。2-创建强类型数据上下文以公开底层表
任何数据驱动的应用程序都有一个提供数据的来源。您的应用程序需要一种方式与此数据源通信。在 LINQ to SQL 术语中,数据上下文完成了此通信的工作。以编程方式,数据上下文是一个派生自 DataContext 基类的类。为了创建强类型数据上下文,您需要派生一个类自 DataContext 基类,如下所示
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Linq.Mapping; using System.Data.Linq; ////// Summary description for trydb /// public class trydb : DataContext { public trydb(string connectionstring) : base(connectionstring) { } public Tableusers; }
trydb 类继承自 DataContext 基类。自定义数据上下文类必须提供一个带有一个参数的构造函数。该构造函数接受数据库连接字符串并将其传递给基类。然而,更有趣的是 users 对象的 Table。这就是您将先前映射的 LINQ to SQL 对象暴露给外部世界的方式。
开发 Web 窗体
3- 按如下方式设计默认的 Web 窗体
Web 窗体包含一个用于基于用户名过滤记录的文本框。 GridView 显示选定的用户记录。选择用户记录后,其详细信息将填充到 DetailsView 中进行编辑。设计完 Web 窗体后,切换到其代码视图。现在我们将编写两个辅助方法 - BindGridView() 和 BindDetailsView()。 BindGridView() 方法使用必需的记录绑定 GridView,如下所示
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Linq.Mapping; using System.Data.Linq; public void BindGridView(string criteria) { string connstr = ConfigurationManager.ConnectionStrings["con"].ConnectionString; trydb tr = new trydb(connstr); IEnumerableresults; if (criteria == string.Empty) { results = tr.users.ToArray(); } else { results=(from c in tr.users where c.UserName.Contains(criteria)select c); } GridView1.DataSource = results; GridView1.DataBind(); }
注意 代码创建了 trydb 类(我们的强类型数据上下文)的一个实例,并将其数据库连接字符串传递给它。为了从 users 表中选择所有记录,您只需使用 trydb 类中的 users Table<>。要获取满足某些条件的记录,您可以使用 C# 语言关键字(from - where - select)并查找用户名包含某些文本的所有用户。结果都收集在一个通用的 IEnumerable 集合中。 BindGridView() 方法从 Page_Load 事件和 Button1_Click 事件调用,如下所示
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindGridView(string.Empty); } }
protected void Button1_Click(object sender, EventArgs e) { BindGridView(TextBox1.Text); }
当您从 GridView 中选择一行时,您需要在 DetailsView 中显示选定的记录以进行编辑。这在另一个辅助方法 - BindDetailsView() 中完成
private void BindDetailedView() { int ID =(int) GridView1.SelectedValue; string connstr = ConfigurationManager.ConnectionStrings["con"].ConnectionString; trydb tr = new trydb(connstr); var result=from emp in tr.users where emp.ID == ID select emp; DetailsView1.DataSource = result; DetailsView1.DataBind(); }
BindDetailsView() 方法从 GridView 的 SelectedIndexChanged 事件处理程序调用。
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) { int ID = (int)GridView1.SelectedValue; string connstr = ConfigurationManager.ConnectionStrings["con"].ConnectionString; BindDetailedView(); }
插入、更新和删除数据
现在让我们看看 LINQ to SQL 中的数据操作是如何工作的。首先,我们将讨论数据插入。
protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e) { string connstr = ConfigurationManager.ConnectionStrings["con"].ConnectionString; trydb tr = new trydb(connstr); users emp = new users(); emp.UserName = ((TextBox)DetailsView1.Rows[1].Cells[1].Controls[0]).Text; emp.Password = ((TextBox)DetailsView1.Rows[2].Cells[1].Controls[0]).Text; tr.users.InsertOnSubmit(emp); tr.SubmitChanges(); BindGridView(string.Empty); BindDetailedView(); }
注意 我们创建了 users 类的一个实例,并从 DetailsView 中输入的USERNAME 和 PASSWORD 新值设置其属性。然后,我们在 users Table 上调用 InsertOnSubmit() 方法以向其添加一个新元素。调用 InsertOnSubmit() 方法只是将新元素插入到 Table 中。要将该行实际添加到数据库,我们需要调用 SubmitChanges() 方法。更新操作与插入类似,只有细微的更改。
protected void DetailsView1_ItemUpdating(object sender, DetailsViewUpdateEventArgs e) { string connstr=ConfigurationManager.ConnectionStrings["con"].ConnectionString; trydb tr = new trydb(connstr); var result=from tt in tr.users where tt.ID == (int)DetailsView1.SelectedValue select tt; result.First().UserName =((TextBox) DetailsView1.Rows[1].Cells[1].Controls[0]).Text; result.First().UserName = ((TextBox)DetailsView1.Rows[2].Cells[1].Controls[0]).Text; tr.SubmitChanges(); BindGridView(string.Empty); BindDetailedView(); }
在这里,我们首先找到与要更新的 ID 匹配的行。然后我们设置其 userName 和 password 属性。注意使用 First() 方法只返回结果中的第一个元素。最后,像以前一样调用 SubmitChanges() 方法。删除操作与插入操作的步骤相同,如下所示
protected void DetailsView1_ItemDeleting(object sender, DetailsViewDeleteEventArgs e) { string strconn = ConfigurationManager.ConnectionStrings["con"].ConnectionString; trydb tr = new trydb(strconn); var result = tr.users.Single(emp => emp.ID == (int)DetailsView1.SelectedValue); tr.users.DeleteOnSubmit(result); tr.SubmitChanges(); BindGridView(string.Empty); BindDetailedView(); }
在这里,我们首先找到要删除的用户记录。请注意使用 Single() 方法来获取单个元素。然后 DeleteOnSubmit() 方法从 Table 中删除用户对象。最后,SubmitChanges() 方法将更改传播到数据库。
我们应该处理 DetailesView 的 modechanging 事件,因为它的模式会根据编辑状态而改变。
protected void DetailsView1_ModeChanging1(object sender, DetailsViewModeEventArgs e) { DetailsView1.ChangeMode(e.NewMode); BindDetailedView(); }
就是这样!运行 Web 窗体并测试其功能。