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

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.55/5 (15投票s)

2007年9月29日

CPOL

4分钟阅读

viewsIcon

67825

downloadIcon

888

有关技术的更多信息,但演示应用程序是 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 数据库开始。

DatabaseStructure.gif

我在该数据库中创建了一个名为 Addresses 的表。

TableStructure.gif

此表相当标准;您唯一必须做的是将 ID 字段设置为自增标志的主键。如果 ID 不是主键,您的应用程序将只读

应用程序

创建 LINQ 类

  • 首先,我们使用 Visual Studio 2008 中的小生成器来创建我们的 LINQ to SQL 类。我将该类命名为 _AddressBook.dbml
    CreateLinqClass.gif
  • 当设计界面出现时,将 Addresses 表拖到设计窗格上。现在将表重命名为 Addresses。通过单击设计窗格中蓝色框顶部的名称来完成此操作。
    DesignPane.gif
  • 转到“属性”窗口并编辑 _AddressBookDataContext 的属性。确保它们的命名空间设置正确,并且连接字符串是从 web.config 中提取的。
    DataContextProperties.gif
  • 接下来,编辑 Address 数据类的属性。默认属性应该没问题。
    AdderssProperties.gif
  • 现在保存并关闭设计器。

包装类

创建一个名为 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 已重新生成,以符合新格式。
© . All rights reserved.