构建一个简单的 LINQ 数据库应用程序






3.55/5 (15投票s)
有关技术的更多信息,但演示应用程序是 ASP.NET
目录
数据库
应用程序
创建 LINQ 类
包装类
应用程序
SQL 查询
演示应用程序
更新
- 2007年12月02日 
- .NET Framework 3.5 发布后已更新以支持其运行。
- Web.config 已更新以反映新发布的程序集。
- default.aspx.cs 的第 103 行使用 DeleteOnSubmit而不是Remove。
- default.aspx.cs 的第 153 行使用 InsertOnSubmit而不是Add。
- _Addressbook.dbml 已重新生成,以符合新格式。
 
- 2007年10月01日 
- 通过使用动态 LINQ,为打包的应用程序和在线演示添加了分页和排序功能。
 
数据库
在此示例应用程序中,我使用的是 SQL 2005 数据库,但您也可以轻松地使用 XML 文件作为数据源。我们将从创建 AddressBook 数据库开始。
 
 
我在该数据库中创建了一个名为 Addresses 的表。
 
 
此表相当标准;您唯一必须做的是将 ID 字段设置为自增标志的主键。如果 ID 不是主键,您的应用程序将只读。
应用程序
创建 LINQ 类
- 首先,我们使用 Visual Studio 2008 中的小生成器来创建我们的 LINQ to SQL 类。我将该类命名为 _AddressBook.dbml。 
- 当设计界面出现时,将 Addresses表拖到设计窗格上。现在将表重命名为Addresses。通过单击设计窗格中蓝色框顶部的名称来完成此操作。 
- 转到“属性”窗口并编辑 _AddressBookDataContext的属性。确保它们的命名空间设置正确,并且连接字符串是从 web.config 中提取的。 
- 接下来,编辑 Address数据类的属性。默认属性应该没问题。 
- 现在保存并关闭设计器。
包装类
创建一个名为 AddressBook 的类。这基本上是一个包装类,用于包装 _AddressBook。此类非常简单;它所做的就是初始化对象并提供对表的便捷访问。唯一的棘手之处在于确保命名空间与您告诉 _AddressBook 使用的命名空间相同,并确保 AddressBookConnectionString 存在于 web.config 中。
using System.Configuration;
/// <summary>
/// Summary description for AddressBook
/// </summary>
namespace Clarity.Database
{
    public class AddressBook
    {
        private _AddressBookDataContext _AddressBook;
        public AddressBook()
        {
            string conn = ConfigurationManager.ConnectionStrings[
                "AddressBookConnectionString"].ToString();
            _AddressBook = new _AddressBookDataContext(conn);
        }
        public System.Data.LINQ.Table<addresses> Addresses
        {
            get { return _AddressBook.Addresses; }
        }
    }
}
应用程序
我不会详细介绍如何构建应用程序,这不重要。但是,我将向您展示如何通过 LINQ 轻松访问您的表。如果您想要完整的应用程序,它在文章的最后。现在进行初始化和访问数据库的繁琐步骤。请稍等;这会有点混乱。
    private AddressBook thisAddressBook = new AddressBook();
就是这样!现在您可以使用 thisAddressBook 对象完全访问您的数据库。使用此对象,您可以通过操作简单的泛型类来查询、插入、更新和删除数据库表中的项。
将数据加载到网格中
    private void LoadGrid()
    {
        GridView1.DataSource = thisAddressBook.Addresses.OrderBy(c =>
此查询输出的数据按 LastName 排序。在 lambda 表达式 (c => c.LastName) 中,c 代表您的对象,也可以是 obj,如 (obj => obj.LastName)。您选择的任何对象名称都可以工作;您只需要在表达式中保持一致。
在网格中筛选数据
    private void LoadGrid(string filter)
    {
        GridView1.DataSource = thisAddressBook.Addresses.Where(
            c =>
这会将数据的一个筛选子集加载到数据源中,其中 LastName 字段必须以 filter 变量指定的内容开头。
删除记录
    protected void GridView1_RowDeleting(object sender, 
        System.Web.UI.WebControls.GridViewDeleteEventArgs e)
    {
        int id = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Value);
        Addresses thisAddress = thisAddressBook.Addresses.First(x =>
第四行(Address thisAddress ...)上的赋值查询数据库以查找指定 ID 的第一个匹配项,并将其分配给 thisAddress。然后,thisAddressBook 对象(我们的表)被告知从表中删除该条目并保存更改。
插入/更新记录
    protected void AddressUpdated(object sender, UserData.UpdateEvent e)
    {
        Addresses thisAddress;
        int id = e.Address.id;
        // If this value is 0 then add a record
        if (id != 0)
            thisAddress = thisAddressBook.Addresses.First(x =>
此函数接收一个已修改或新创建的 Addresses 对象,并将其更新或插入到表中。
SQL 查询
我很有兴趣了解查询实际向数据库发出的命令。它是否会加载所有记录,然后对其进行筛选?它是否会定制查询以仅获取所需的信息?我只能说,我对结果非常满意……
LoadQuery 的结果
SELECT [t0].[id], [t0].[FirstName],
[t0].[LastName], [t0].[Address1], [t0].[City], [t0].[State], [t0].[Zip],
[t0].[Email] FROM [dbo].[Addresses] AS [t0] ORDER BY [t0].[LastName]
好的,这没什么不寻常的。
筛选查询的结果
exec sp_executesql N'SELECT
[t0].[id], [t0].[FirstName], [t0].[LastName], [t0].[Address1], [t0].[City],
[t0].[State], [t0].[Zip], [t0].[Email] FROM [dbo].[Addresses] AS [t0] WHERE
[t0].[LastName] LIKE @p0 ORDER BY [t0].[LastName]',N'@p0 nvarchar(2)',@p0=N'H%'
啊,它正在使用 SP 作为安全措施来防范 SQL 注入攻击。
Delete Query 的结果
exec sp_executesql N'DELETE FROM
[dbo].[Addresses] WHERE ([id] = @p0) AND ([FirstName] = @p1) AND ([LastName] =
@p2) AND ([Address1] = @p3) AND  ([City] = @p4) AND ([State] = @p5) AND ([Zip]
= @p6) AND ([Email] = @p7)',N'@p0 int,@p1 nvarchar(5),@p2 nvarchar(5),@p3
nvarchar(15),@p4  nvarchar(10),@p5 nvarchar(2),@p6 nvarchar(5),
@p7 nvarchar(15)',@p0=4,@p1=N'Kelly',@p2=N'Smith',@p3=N'123
Fake  Street',@p4=N'Manchester',@p5=N'NH',@p6=N'03102',@p7=N'kelly@gmail.com'
这与上面相同。
Insert Query 的结果
exec sp_executesql N'INSERT INTO
[dbo].[Addresses]([FirstName], [LastName], [Address1], [City], [State], [Zip],
[Email]) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6)
SELECT [t0].[id] FROM
[dbo].[Addresses] AS [t0] WHERE [t0].[id] = (SCOPE_IDENTITY()) ',N'@p0
varchar(7),@p1 varchar(6),@p2 varchar(15),@p3 varchar(9),@p4 varchar(2),@p5
varchar(5),@p6  varchar(18)',@p0='John',@p1='Smith',@p2='123 Fake
Street',@p3='Somewhere',@p4='CT',@p5='03102',@p6='nobody@nowhere.com'
插入似乎会重新查询数据以检索新创建的主键的值。
演示应用程序
演示应用程序是用 Visual Studio 2008 构建的,并用 C# 编写。这绝不是一个完成的产品;它只是展示了您使用 LINQ 可以做什么的快速演示。
历史
- 2007 年 9 月 30 日 -- 发布原始版本
- 2007 年 11 月 8 日 -- 更新了文章内容
- 2007 年 12 月 14 日 -- 更新了下载;文章被编辑并移至 CodePoroject.com 的主要文章库- 已更新以支持 .NET Framework 3.5 的发布。
- Web.config 已更新以反映新发布的程序集。
- default.aspx.cs 的第 103 行使用 DeleteOnSubmit 而不是 Remove。
- default.aspx.cs 的第 153 行使用 InsertOnSubmit 而不是 Add。
- _Addressbook.dbml 已重新生成,以符合新格式。
 


