建立实体类
使用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组件进行数据库建模的基本教程的详细内容...