🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
ado.net提供了对c#连接数据库的支持,而sql server作为各大数据库中的其中一员对ado.net最友好。 ###起步 一、下载并安装sql server 本人安装的是sql server2008r x64 中文版,可自行百度去下载并安装,无需任何注意事项。 二、导入sql server到实际项目中 1、打开vs,创建一个项目,该实例创建的是控制台项目 ![](https://box.kancloud.cn/5aaa8132874826a08ea986b9aff221f9_711x410.png) ![](https://box.kancloud.cn/1607901c53f5136c44e344e522349f73_1294x474.png) 2、在"项目"上单击右键选择新建项,在弹出的框中选择“基于服务的数据库” ![](https://box.kancloud.cn/455e82593c9dd8a4de0b550d99ec5998_1304x596.png) 3、选择数据集并点击下一步 ![](https://box.kancloud.cn/d53cd3d41f290f802c2f5bc504f10715_661x592.png) 4、点击完成即可,你会发现解决方案中多了一个.mdf的文件 ![](https://box.kancloud.cn/33845933cd15128dc10f42096b205b4d_381x333.png) 我们点击服务器资源管理器会看到整个数据库的信息 ![](https://box.kancloud.cn/8a3fd666d7954b9be24c535bb0313e60_393x433.png) 5、下面来创建新表 右键单击“表”文件夹选择添加新表,在弹出的选项卡内可以进行建表的操作。 在名称前面一格右键可以设置主键外键等 ![](https://box.kancloud.cn/d0cee72eaf22b1193bc121569c7842b5_584x177.png) 点击每一列在右下角都会有该列的详细信息,按规范来讲每个表都应该有id列,我推荐将id设为标识(自增),默认增量是1。为什么这么做?因为id往往作为一个表的主键,通常也是其他表的外键,将它设为自增后我们在插数据的时候不需要关系id,它自己会随着数据的增多而自增 ![](https://box.kancloud.cn/456f4fa487a52d99551dbf365034cf96_404x293.png) 6、完成 在这里可以把Table替换成自己需要的表名(这里有个坑,先记一下) ![](https://box.kancloud.cn/0386600f5e024112502306a9f28b5e1e_352x173.png) 建表完毕后,点击左上角的更新,更新数据库,然后刷新一下数据库,就可以看到表已经新建 ![](https://box.kancloud.cn/9b5706054fc9f5142cc175597489d47a_376x336.png) 三、编写代码 1、右键单击“引用”,选择添加引用,选中System.Configuration,点击确定 2、将下面三个引用添加到最上面 ``using System.Data; using System.Data.SqlClient; using System.Configuration;`` 3、链接数据库 这里先说一个坑,在连接数据库之前必须输入一下代码,否则在查看数据库数据的时候会报“sql server版本不兼容”的问题,因为存在控制台应用中数据库的链接路径的bug,听说asp.net web项目不会出现这种问题,不过我还没试,为了以防万一还是先写上吧 ~~~ string dataDir = AppDomain.CurrentDomain.BaseDirectory; if (dataDir.EndsWith(@"\bin\Debug\") || dataDir.EndsWith(@"\bin\Release")) { dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName; AppDomain.CurrentDomain.SetData("DataDirectory", dataDir); } ~~~ 4、创建数据库实例 ~~~ string strConnection = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True"; ~~~ 上面那一串字符串是哪来的?我们打开App.config配置文件,add name就是我们刚刚导入数据库的时候自动添加的。name就是这一整串字符串的名字,稍后会用到。connectionString就是记录了链接数据库的各种信息,我们把connectionString里面的内容复制一下放到一个字符串中,也就是上面的strConnection,记得加上一个@,这样遇到特殊字符"\"就不必额外转义了 ~~~ <connectionStrings> <add name="str" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> ~~~ 5、链接数据库,SqlConnection就是数据库实例,它接收一个字符串 ~~~ SqlConnection objConnection = new SqlConnection(strConnection); ~~~ 6、打开链接 ~~~ objConnection.Open(); ~~~ 7、创建一个数据库的查询对象,用于携带sql语句 ~~~ SqlCommand sqlc = objConnection.CreateCommand(); ~~~ 8、添加sql语句(注意,如果要插入的是字符串要用单引号括起来,因为整个sql语句本身就是字符串,字符串中的字符串用的是单引号) ~~~ sqlc.CommandText = "Insert into text(name,age) values ('qinchuan',22)"; ~~~ 9、执行该sql语句(像插入删除这类不反回结果的操作使用ExecuteNonQuery方法,也就是非查询语句) ~~~ sqlc.ExecuteNonQuery(); ~~~ 10、现在来测试一下,点击运行,运行结束后在“服务器资源管理器”中找到刚刚操作的表,右键单击“显示表数据” ![](https://box.kancloud.cn/2fbfad1222d9d137f879efe20f02fa65_482x244.png) 数据插入成功,你会发现sql语句中并没有插入id,但是id自动插入了,而且如果有多个数据,id是自增的,这就是我刚刚说的要把id设为标识的好处,我们不必关心id的值是多少了。 附上源代码 ~~~ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string dataDir = AppDomain.CurrentDomain.BaseDirectory; if (dataDir.EndsWith(@"\bin\Debug\") || dataDir.EndsWith(@"\bin\Release")) { dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName; AppDomain.CurrentDomain.SetData("DataDirectory", dataDir); } string strConnection = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True"; SqlConnection objConnection = new SqlConnection(strConnection); objConnection.Open(); SqlCommand sqlc = objConnection.CreateCommand(); sqlc.CommandText = "Insert into text(name,age) values ('qinchuan',22)"; sqlc.ExecuteNonQuery(); Console.ReadKey(); } } } ~~~ 11、如果我的sql语句是例如select的查询语句呢?也就是说我需要对返回的结果进行操作怎么办?我们这时候就不能使用ExecuteNonQuery了,举个例子: 先来接收用户的输入 ~~~ Console.WriteLine("请输入用户名"); string username = Console.ReadLine(); ~~~ 根据用户输入的用户名来查询数据库,注意我sql语句的书写方式 ~~~ sqlc.CommandText = "select * from M_User where username='" + username+"'"; ~~~ 使用SqlDataReader对象来接收返回的数据 ~~~ SqlDataReader sdr = sqlc.ExecuteReader(); ~~~ 我们假设现在表中有username字段和password字段,我想通过用户输入的用户名找到该用户名相应的密码怎么办?使用GetType(Type根据你数据库字段类型而定,这里的password数据库中存入的是字符创varchar,所以用string),GetType的参数是一个整数,代表返回结果集中第几列的数据,SqlDataReader的GetOriginal的参数是一个字符串,代表结果集中该字符串的位置。比如查找qinchuan这个用户,他的密码在第三列,通过GetOriginal("password")可以拿到index为2,然后GetString(2)就可以拿到它的密码了 ~~~ string rpassword = sdr.GetString(sdr.GetOrginal("password")); ~~~ ###优化 我们在链接数据库的时候将App.config文件中的那一串字符串拷贝过来保存到一个字符串类型变量中,然后将该字符串作为参数传入到SqlConnection中 ~~~ string strConnection = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True"; SqlConnection objConnection = new SqlConnection(strConnection); ~~~ 这种方法乍一看很简单,但是当文件越来越多的时候,如果数据库链接的字符串有变动,那么要改的地方会非常多,有一种十分渐简便的方法,我们可以直接使用配置文件中的信息,不必非要把它复制过来,还记得我之前说要引入System.Configuration这个引用了吗?我们可以使用ConfigurationManager来得到相应的配置文件的信息 ~~~ ConfigurationManager.ConnectionStrings["str"].ToString() ~~~ 上面的“str”就是我的配置文件的name ![](https://box.kancloud.cn/d64947ff339d95d51e08bbce5af0e16a_889x103.png) 对比一下这两种方法,你会发现下面的方法很简单,当有变动的时候只需要更改配置文件里面的信息就可以了 ~~~ SqlConnection objConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["str"].ToString()); ~~~ 还记得我之前说过的一个坑吗? ![](https://box.kancloud.cn/dff7bcf2f8ad3b230b1fda960dc2dbc8_517x207.png) 你可以尝试在建表的时候把表的名字设为user,你会发现当程序执行的时候会报错:user附近有非法的标识符。这是因为user默认是sql的关键字,你是不能把一个关键字作为表名的,有两种解决方法 1、使用“[表名]”来避免 ~~~ sqlc.CommandText = "select * from [user] where username='" + username+"'"; //注意user被[]包了起来 ~~~ 2、换个表名