欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#操作LINQ to SQL组件进行数据库建模的基本教程

程序员文章站 2022-11-23 23:49:11
建立实体类 使用linq to sql时,需要首先建立用于映射数据库对象的模型,也就是实体类。在运行时,linq to sql 根据linq表达式或查询运算符生成sql语...

建立实体类
使用linq to sql时,需要首先建立用于映射数据库对象的模型,也就是实体类。在运行时,linq to sql 根据linq表达式或查询运算符生成sql语句,发送到数据库进行操作。数据库返回后,linq to sql负责将结果转换成实体类对象。

建立实体类的方法有很多,例如linq to sql设计器,手动编码建立,使用xml文件映射,使用命令行工具sqlmetal生成等。其中最方便的就是linq to sql设计器。

1.使用linq to sql设计器建立实体类        
在一个示例用的demo控制台程序中添加一个“基于服务的数据库”database1.mdf,建立一张tb_guestinfo的表。该表的详细如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程

下面的所有建立方式,都用的这个数据库。

在项目中添加一个linq to sql类,采用默认的名称dataclasses1.dbml,如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程

将tb_guestinfo表拖到界面上,保存。

C#操作LINQ to SQL组件进行数据库建模的基本教程

ok,编写相关代码如下,实现增删改查:

using system;
using system.collections.generic;
using system.linq;
using system.text;

namespace linq_to_sql自定义数据库和实体类
{
  /// <summary>
  /// 实体类的建立___1.vs建立实体类
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      //
      dataclasses1datacontext dc = new dataclasses1datacontext();
      
      //1.查询
      iqueryable<tb_guestinfo> query = from p in dc.tb_guestinfo
                       where p.name != "xxx"
                       select p;

      foreach (var g in query)
      {
        console.writeline("{0} {1} {2} {3}",g.id,g.name,g.age ,g.tel );
      }

      console.writeline("-----------------");
      console.readkey(false);
      //2.增加一条记录
      tb_guestinfo ginfo = new tb_guestinfo() { id = 9, name = "m&m", age = 40, tel = "135****5555" };
      dc.tb_guestinfo.insertonsubmit(ginfo);
      dc.submitchanges();

      foreach (var g in query)
      {
        console.writeline("{0} {1} {2} {3}",g.id , g.name, g.age, g.tel);
      }

      console.writeline("-----------------");
      console.readkey(false);

      //3.删除
      var query_itemtodelete = from g in dc.tb_guestinfo
                   where g.name == "m&m"
                   select g;
      foreach (var g in query_itemtodelete)
      {
        dc.tb_guestinfo.deleteonsubmit(g);
      }
      dc.submitchanges();


      foreach (var g in query)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("-----------------");
      console.readkey(false);

      //4.修改
      var query_itemtoupdate = from g in dc.tb_guestinfo
                   where g.name.contains("debuglzq")
                   select g;

      foreach (var g in query_itemtoupdate)
      {
        g.name = g.name + "a";
      }
      dc.submitchanges();


      foreach (var g in query)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }

      console.writeline("-----------------");
      console.readkey(false);

    }
  }
}

程序运行结果如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程

2.手动建立实体类                    
实体类在多数情况下可以通过linq to sql类设计器建立,当然动手建立一个简单的实体类也不是难事,并且可以更好的学习linq to sql的对象模型。数据库依然是前面的示例数据库。

在项目中添加一个类guestinfoentity.cs,如下:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.data.linq.mapping;

namespace datacontexdemo
{
  /// <summary>
  /// 手动建立实体类
  /// </summary>
  [table(name="tb_guestinfo")]
  class guestinfoentity
  {
    [column(isprimarykey=true,dbtype="int not null identity",isdbgenerated=true,name="id")]
    public int id { get; set; }

    [column(dbtype = "nvarchar(20)", name = "name")]
    public string name{get;set;}

    [column(dbtype = "int", name = "age")]
    public int age { get; set; }

    [column(dbtype = "nvarchar(20)", name = "tel")]
    public string tel { get; set; }
  }
}

编写示例代码,注意需要引入system.data.linq.dll:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.data.linq;//关注

namespace datacontexdemo
{
  class program
  {
    static void main(string[] args)
    {
      //2.手动建立实体类
      //
      //连接字符串
      string constring = @"data source=.\sqlexpress;attachdbfilename=e:\visual studio 2010\linq_to_sql\linq_to_sql自定义数据库和实体类\database1.mdf;integrated security=true;user instance=true";

      datacontext dc = new datacontext(constring);

      table<guestinfoentity> tb = dc.gettable<guestinfoentity>();

      var query = tb.asenumerable();

      foreach (var q in query)
      {
        console.writeline("{0} {1} {2} {3}",q.id,q.name,q.age,q.tel );
      }

      console.readkey();
    }
  }
}

程序运行如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程

3.使用xml映射文件建立实体类                         
 实体类的映射除了使用内联attribute外,还可以建立一个包含映射信息的xml文件,此文件生成system.data.linq.mapping.xmlmappingsource对象,作为datacontext对象构造方法的参数。

这个xml文件只有一个根节点---database元素,用来映射的数据库信息。database元素包含一个或多个table元素,用于映射数据库表的信息,table元素由一个type元素和多个column元素(或association元素)组成。type元素用来指定实体类,column元素用来指定列信息,association元素用来映射数据库关系。

在项目中添加一个xml文件,采用默认名称xmlfile1.xml,内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<database name="database1" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007"><!--数据库名称可随意;名称空间一定要加上-->
 <table name="tb_guestinfo"><!--数据库中表的名称-->
  <type name="linqtosql建立实体类_xml.guestinfoentity"><!--太bt了,居然要全名;guestinfoentity居然不行-->  
   <column name="id" member="id" dbtype="int not null identity" isprimarykey="true"/>
   <column name="name" member="name" dbtype="nvarchar(20)" />
   <column name="age" member="age" dbtype="int" />
   <column name="tel" member="tel" dbtype="nvarchar(20)" />
  </type>
 </table>
</database>

这个xml文件包含类全部的映射信息,下面建立映射的类guestinfoentity.cs:

using system;
using system.collections.generic;
using system.linq;
using system.text;

namespace linqtosql建立实体类_xml
{
  public class guestinfoentity
  {    
    public int id { get; set; }
    
    public string name { get; set; }
    
    public int age { get; set; }
    
    public string tel { get; set; }
  }
}

编写示例代码,同样需要引入system.data.linq.dll:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.data.linq;
using system.data.linq.mapping;
using system.io;//

namespace linqtosql建立实体类_xml
{
  class program
  {
    static void main(string[] args)
    {
      string constring = @"data source=.\sqlexpress;attachdbfilename=e:\visual studio 2010\linq_to_sql\linq_to_sql自定义数据库和实体类\database1.mdf;integrated security=true;user instance=true";

      xmlmappingsource map = xmlmappingsource.fromxml(file.readalltext("xmlfile1.xml"));

      datacontext dc = new datacontext(constring, map);

      table<guestinfoentity> tb = dc.gettable<guestinfoentity>();

      var query = tb.asenumerable();

      foreach (var g in query)
      {
        console.writeline("{0} {1} {2} {3}",g.id,g.name,g.age,g.tel );
      }
      console.readkey();
    }
  }
}

程序的运行如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程


用于数据库连接的datacontext对象成员
datacontext类位于system.data.linq.dll程序集中的system.data.linq名称空间下。在linq to sql中负责实体对象和数据库之间的数据交换及其他数据库操作,还负责把数据库中的数据映射成实体类的实例。

datacontext是linq to sql操作实体类建立后紧接着需要操作的对象。本文总结其常用函数和属性的作用及常用用法,实体类是上一节的guestinfo.cs类,数据库也采用上一节的数据库database1.mdb,下面的示例程序对对象和属性按其功能进行了必要的分组,代码中也有详尽的注释。代码如下:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.data.linq;
using system.io;
using system.data.sqlclient;

namespace datacontext对象成员
{
  /// <summary>
  /// 用于数据库连接的datacontext类成员
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      
      //连接字符串
      string constring = @"data source=.\sqlexpress;attachdbfilename=e:\visual studio 2010\linq_to_sql\linq_to_sql自定义数据库和实体类\database1.mdf;integrated security=true;user instance=true";
      //1.构造函数
      datacontext dc = new datacontext(constring);
      //2.gettable
      table<guestinfoentity> table = dc.gettable<guestinfoentity>();
      var query = table.asenumerable();
      foreach(var g in query)
      {
        console.writeline("{0} {1} {2} {3}",g.id,g.name,g.age,g.tel );
      }
      console.writeline("-----------------");
      console.readkey();

      string filename = @"e:\visual studio 2010\linq_to_sql\linq_to_sql自定义数据库和实体类\database1.mdf";
      //3.databaseexists、deletedatabase、createdatabase
      if (dc.databaseexists())
      {
        console.writeline("数据库文件已经存在.");
        dc.deletedatabase();
      }
      dc.createdatabase();
      if (dc.databaseexists())
      {
        console.writeline("{0} 数据库文件创建成功.",path.getfilename(filename ));
      }
      console.writeline("-----------------");
      console.readkey();
      //4_1.executecommand 作为linq补充直接用sql指令操作数据库
      dc.executecommand("insert into tb_guestinfo(name,age,tel) values({0},{1},{2})","debuglzq",25,"198****1336");

      foreach (var r in dc.gettable<guestinfoentity>())
      {
        console.writeline("{0} {1} {2} {3}",r.id,r.name,r.age,r.tel );
      }
      console.writeline("-----------------");
      console.readkey();
      //4_2.executequery 作为linq补充直接用sql指令操作数据库
      var rows= dc.executequery<guestinfoentity>("select * from tb_guestinfo");

      foreach (var r in rows)
      {
        console.writeline("{0} {1} {2} {3}", r.id, r.name, r.age, r.tel);
      }
      console.writeline("-----------------");
      console.readkey();
      //4_3translate 将dbreader转换为linq对象
      string querystring = "select * from tb_guestinfo";
      sqlconnection connection = new sqlconnection(constring);
      sqlcommand cmd = new sqlcommand(querystring, connection);
      connection.open();

      var result = dc.translate<guestinfoentity>(cmd.executereader());//ado.net转换linq

      foreach (var r in result)
      {
        console.writeline("{0} {1} {2} {3}", r.id, r.name, r.age, r.tel);
      }
      connection.close();
      console.writeline("-----------------");
      console.readkey();
      //5.submitchanges 应用修改
      var firstrow = (from p in dc.gettable<guestinfoentity>()            
            select p).first();
      firstrow.name =firstrow.name +"a";

      dc.submitchanges();//应用修改

      foreach (var r in dc.gettable<guestinfoentity>() )
      {
        console.writeline("{0} {1} {2} {3}", r.id, r.name, r.age, r.tel);
      }
      console.writeline("-----------------");
      console.readkey();
      //6.getchangeset方法 返回datacontext对象插入、删除、修改过的对象
      changeset cs = dc.getchangeset();
      foreach (var r in cs.updates )
      {
        guestinfoentity t = r as guestinfoentity;
        console.writeline("{0} {1} {2} {3}", t.id,t.name,t.age,t.tel );
      }
      console.writeline("-----------------");
      console.readkey();
      //7.refresh刷新实体对象
      var row1=(from g in dc.gettable<guestinfoentity>() select g).first();
      row1.age = row1.age + 5;
      dc.submitchanges();
      dc.refresh(refreshmode.overwritecurrentvalues, row1);//

      foreach (var r in dc.gettable<guestinfoentity>())
      {
        console.writeline("{0} {1} {2} {3}", r.id, r.name, r.age, r.tel);
      }
      console.writeline("7-----------------");
      console.readkey();
      //changeconflicts属性 返回datacontext操作数据库时产生的并发冲突合集

      //transaction属性 设置或返回datacontext跟其他ado.net程序共享的事物对象

      //objecttrackingenabled属性 开启或关闭datacontext实体对象的状态跟踪   
   
      //8.log属性 返回datacontext产生的sql命令
      dc.log = console.out;//控制台输出datacontext产生的sql语句

      foreach (var r in dc.gettable<guestinfoentity>())
      {
        console.writeline("{0} {1} {2} {3}", r.id, r.name, r.age, r.tel);
      }
      console.writeline("-----------------");
      console.readkey();

    }
  }
}

程序中的注释很详细,不再赘述。

程序的运行结果如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程


操作单一表格的table<tentity>类
前面介绍了datacontext类,它可以用来映射和连接数据库,执行sql命令,跟踪实体对象的状态。

下面介绍table<tentity>表示表格记录,它是一个泛型集合类,它的元素就是表格实体对象。它提供一组方法,对元素进行添加删除操作,并可以通过datacontext将这些操作保存到数据库。

表还是前面的那张表,在项目中添加了一个linq to sql类。重点是insertonsubmit、deleteonsubmit等方法。

using system;
using system.collections.generic;
using system.linq;
using system.text;

namespace linq_to_sql_table
{
  /// <summary>
  /// 操作单一表格的table<tentity>类
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      //1.a.attach附加实体
      dataclasses1datacontext dc1 = new dataclasses1datacontext();
      tb_guestinfo guset = new tb_guestinfo() { id=1, name = "debuglzq", age = 35, tel = "138****8888" };

      dc1.tb_guestinfo.attach(guset);//这样的attach仅仅附加实体,数据库没有更新
      dc1.submitchanges();
      //显示附加成功
      foreach (var g in dc1.tb_guestinfo)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("---------");
      //显示数据库没有更新
      dataclasses1datacontext dc2 = new dataclasses1datacontext();
      foreach (var g in dc2.tb_guestinfo)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("------------------------");
      console.readkey();

      //2.insertonsubmit
      dc2.tb_guestinfo.insertonsubmit(guset);
      dc2.submitchanges();

      foreach (var g in dc2.tb_guestinfo)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("------------------------");
      console.readkey();
      //2b.insertallonsubmit 插入集合
      list<tb_guestinfo> lst = new list<tb_guestinfo>() 
      {
        new tb_guestinfo(){ name="aa", age=25,tel="133****3333"},
        new tb_guestinfo(){ name="bb", age=25,tel="135****5555"}
      };
      dc2.tb_guestinfo.insertallonsubmit(lst);
      dc2.submitchanges();

      foreach (var g in dc2.tb_guestinfo)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("------------------------");
      console.readkey();
      //
      //3.deleteonsubmit
      tb_guestinfo entity = (from g in dc2.tb_guestinfo
                  where g.name == "aa"
                  select g).single();
      dc2.tb_guestinfo.deleteonsubmit(entity);//
      dc2.submitchanges();

      foreach (var g in dc2.tb_guestinfo)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("------------------------");
      console.readkey();
      //3b.deleteallonsubmit
      ienumerable<tb_guestinfo> entitys = from g in dc2.tb_guestinfo
                        where g.name == "aa" || g.name == "bb"
                        select g;
      dc2.tb_guestinfo.deleteallonsubmit(entitys);
      dc2.submitchanges();

      foreach (var g in dc2.tb_guestinfo)
      {
        console.writeline("{0} {1} {2} {3}", g.id, g.name, g.age, g.tel);
      }
      console.writeline("------------------------");
      console.readkey();      
      
    }
  }
}

程序运行结果如下:

C#操作LINQ to SQL组件进行数据库建模的基本教程