zoukankan      html  css  js  c++  java
  • 一步一步学Linq to sql(二):DataContext与实体

       

    DataContext

     

           DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修改写入数据库。

           DataContext提供了以下一些使用的功能:

    l         以日志形式记录DataContext生成的SQL

    l         执行SQL(包括查询和更新语句)

    l         创建和删除数据库

    DataContext是实体和数据库之间的桥梁,那么首先我们需要定义映射到数据表的实体。

     

    定义实体类

     

    using System.Data.Linq.Mapping;

     

    [Table(Name = "Customers")]

    public class Customer

    {

        [Column(IsPrimaryKey = true)]

        public string CustomerID {get; set;}

     

        [Column(Name = "ContactName")]

        public string Name { get; set; }

     

        [Column]

        public string City {get; set;}

    }

           Northwind数据库为例,上述Customers类被映射成一个表,对应数据库中的 Customers表。然后在类型中定义了三个属性,对应表中的三个字段。其中,CustomerID字段是主键,如果没有指定Column特性的Name属性,那么系统会把属性名作为数据表的字段名,也就是说实体类的属性名就需要和数据表中的字段名一致。

           现在,创建一个ASP.NET页面,然后在页面上加入一个GridView控件,使用下面的代码进行绑定数据:

    using System.Data.Linq;

     

    DataContext ctx = new DataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    Table<Customer> Customers = ctx.GetTable<Customer>();

    GridView1.DataSource = from c in Customers where c.CustomerID.StartsWith("A") select new {顾客ID=c.CustomerID, 顾客名=c.Name, 城市=c.City};

    GridView1.DataBind();

           使用DataContext类型把实体类和数据库中的数据进行关联。你可以直接在DataContext的构造方法中定义连接字符串,也可以使用IDbConnection

    using System.Data.SqlClient;

     

    IDbConnection conn = new SqlConnection("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    DataContext ctx = new DataContext(conn);

           之后,通过GetTable获取表示底层数据表的Table类型,显然,数据库中的Customers表的实体是Customer类型。随后的查询句法,即使你不懂SQL应该也能看明白。从Customers表中找出CustomerID以“A”开头的记录,并把CustomersIDName以及City封装成新的匿名类型进行返回。

           结果如下图:

     

     

    强类型DataContext

     

    public partial class NorthwindDataContext : DataContext

    {

        public Table<Customer> Customers;

        public NorthwindDataContext(IDbConnection connection) : base(connection) { }

        public NorthwindDataContext(string connection) : base(connection) { }

    }

           强类型数据上下文使代码更简洁:

    NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    GridView1.DataSource = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顾客ID = c.CustomerID, 顾客名 = c.Name, 城市 = c.City };

    GridView1.DataBind();

           DataContext其实封装了很多实用的功能,下面一一介绍。

     

    日志功能

     

    using System.IO;

     

    NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    StreamWriter sw = new StreamWriter(Server.MapPath("log.txt"), true); // Append

    ctx.Log = sw;

    GridView1.DataSource = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顾客ID = c.CustomerID, 顾客名 = c.Name, 城市 = c.City };

    GridView1.DataBind();

    sw.Close();

           运行程序后在网站所在目录生成了log.txt,每次查询都会把诸如下面的日志追加到文本文件中:

    SELECT [t0].[CustomerID], [t0].[ContactName], [t0].[City]

    FROM [Customers] AS [t0]

    WHERE [t0].[CustomerID] LIKE @p0

    -- @p0: Input String (Size = 2; Prec = 0; Scale = 0) [A%]

    -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

           应该说这样的日志对于调试程序是非常有帮助的。

     

    探究查询

     

    using System.Data.Common;

    using System.Collections.Generic;

     

    NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    var select = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顾客ID = c.CustomerID, 顾客名 = c.Name, 城市 = c.City };

    DbCommand cmd = ctx.GetCommand(select);

    Response.Write(cmd.CommandText + "<br/>");

    foreach (DbParameter parm in cmd.Parameters)

        Response.Write(string.Format("参数名:{0},参数值:{1}<br/>", parm.ParameterName, parm.Value));

    Customer customer = ctx.Customers.First();

    customer.Name = "zhuye";

    IList<object> queryText = ctx.GetChangeSet().ModifiedEntities;

    Response.Write(((Customer)queryText[0]).Name);

           在这里,我们通过DataContextGetCommand方法获取了查询对应的DbCommand,并且输出了CommandText和所有的DbParameter。之后,我们又通过GetChangeSet方法获取了修改后的实体,并输出了修改内容。

     

    执行查询

     

    NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    string newcity = "Shanghai";

    ctx.ExecuteCommand("update Customers set City={0} where CustomerID like 'A%'", newcity);

    IEnumerable<Customer> customers = ctx.ExecuteQuery<Customer>("select * from Customers where CustomerID like 'A%'");

    GridView1.DataSource = customers;

    GridView1.DataBind();

           前一篇文章已经说了,虽然Linq to sql能实现90%以上的TSQL功能。但是不可否认,对于复杂的查询,使用TSQL能获得更好的效率。因此,DataContext类型也提供了执行SQL语句的能力。代码的执行结果如下图:

     

     

    创建数据库

     

    testContext ctx = new testContext("server=xxx;database=testdb;uid=xxx;pwd=xxx");

    ctx.CreateDatabase();

     

    [Table(Name = "test")]

    public class test

    {

        [Column(IsPrimaryKey = true, IsDbGenerated = true)]

        public int ID { get; set; }

     

        [Column(DbType="varchar(20)")]

        public string Name { get; set; }

    }

     

    public partial class testContext : DataContext

    {

        public Table<test> test;

        public testContext(string connection) : base(connection) { }

    }

           这段代码在数据库中创建了名为testdb的数据库,等同于下面的脚本:

    CREATE TABLE [dbo].[test](

        [ID] [int] IDENTITY(1,1) NOT NULL,

        [Name] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL,

     CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED

    (

        [ID] ASC

    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

    ) ON [PRIMARY]

           同时,DataContext还提供了DeleteDatabase()方法,在这里就不列举了。

     

    使用DbDataReader数据源

     

    using System.Data.SqlClient;

     

    var conn = new SqlConnection("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

    var ctx = new DataContext(conn);

    var cmd = new SqlCommand("select * from customers where CustomerID like 'A%'", conn);

    conn.Open();

    var reader = cmd.ExecuteReader();       

    GridView1.DataSource = ctx.Translate<Customer>(reader);

    GridView1.DataBind();

    conn.Close();

           你同样可以选择使用DataReader获取数据,增加了灵活性的同时也增加了性能。

     

    看到这里,你可能会觉得手工定义和数据库中表对应的实体类很麻烦,不用担心,VS2008提供了自动生成实体类以及关系的工具,工具的使用将在以后讲解。今天就讲到这里,和DataContext相关的事务、加载选项、并发选项以及关系实体等高级内容也将在以后讲解。

  • 相关阅读:
    unsupported jsonb version number 123
    如何在MPlayer上支持RTSP
    TDengine 时序数据库的 ADO.Net Core 提供程序 Maikebing.EntityFrameworkCore.Taos
    如何使用IoTSharp对接ModBus?
    如何从源码启动和编译IoTSharp
    Asp.Net Core 自动适应Windows服务、Linux服务、手动启动时的内容路径的扩展方法
    MQTTnet 的Asp.Net Core 认证事件的扩展
    Asp.Net Core 中利用QuartzHostedService 实现 Quartz 注入依赖 (DI)
    The remote certificate is invalid according to the validation procedure 远程证书验证无效
    settings插拔式源码
  • 原文地址:https://www.cnblogs.com/lovecherry/p/856977.html
Copyright © 2011-2022 走看看