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.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(); } } }
程序的运行如下:
用于数据库连接的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(); } } }
程序运行结果如下:
相关文章
- 我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25