好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#操作LINQ to 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的表。该表的详细如下:

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

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

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

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 );

 

     }

   }

}

程序运行结果如下:

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();

     }

   }

}

程序运行如下:

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测试数据/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();

     }

   }

}

程序的运行如下:


用于数据库连接的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();

 

     }

   }

}

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

程序的运行结果如下:

 


操作单一表格的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();     

      

     }

   }

}

程序运行结果如下:

dy("nrwz");

查看更多关于C#操作LINQ to SQL组件进行数据库建模的基本教程的详细内容...

  阅读:73次