ado.net

区别,运行的时候会自动附加
(Attach).
双击mdf文件会在"服务器资源管理器"中打开,管理方式和在
Management Studio没有什么本质不同。要拷贝mdf文件需要关闭
所有指向mdf文件的链接。
 
正式生产运行的时候附加到sqlserver上、修改连接字符串即可
,除此之外没有任何的区别,在"数据库"节点上点右键"附加";在
数据库节点上->任何-->分离就可以得到可以考来考去mdf文件。
用的时候要在控制台、winform项目中在main函数最开始的位置
加入备注中的代码。asp.net项目中不需要。
 
详细介绍:http://www.rupeng.com/forum/thread-11988-1-
1.html
 
 
class4ADO.net详解
链接sql server程序要和数据库交互要通过ado.net进行,通过ado.net就能在程
序中执行sql了。ado.net中提供了对各种不同数据库的统一操作
接口。
直接在项目中内嵌mdf文件的方式使用sqlserver数据库(基于
服务的数据库)。mdf文件随着项目走,用起来方便,和在数据库
服务器上创建数据库没什么
链接字符串:程序通过链接字符串 指定要连那台服务器上的哪个
实例的那个数据库、用什么用户名密码等。
 
项目内嵌mdf文件形式的链接字符串"Data Source=.
\SQLEXPRESS;AttachDBFilename=|DataDirectory|
\Database1.mdf:Integrated Security=True:User
Instance=True".".\SQLEXPRESS"表示"本机上的SQLEXPRESS实
例",如果数据库实例名不是SQLEXPRESS,则需要修
改。"Database1.mdf"为mdf的文件名。
ADO.Net中通过SqlConnection类创建到SQLServer的链接,
SqlConnection代表一个数据库链接,ADO.Net中的链接等资源都
实现了IDisposable接口,可以使用using进行资源管理。执行备
注中的代码如果成功了就ok.
 
方法二 打开VS 项目 服务器资源管理器 —》 数据连接
   —》 右键 添加连接
最后 连接到一个数据库 有则选择 数据库名称 没有就
输入一个 会提示新建一个数据库
这样就可以在新数据库中进行新建 表等操作
 
 
如果你不用App.config(Web.config)配置的话,可以直接在程序
中加入以下连接:
string ConStr= "server=.;database=数据库;user
id=sa;password=密码";
SqlConnection conn = new SqlConnection(ConStr);
conn.Open();
就可以打开数据库进行操作了。
如果用App.config配置的话,先在App.config(Web.config)中
加入
 <appSettings>
    <add key="ConStr"
value="server=.;database=XiaoQuWuYeMS_DB;uid=sa;pwd=;"
/>
  </appSettings>
然后在连接页面用
private readonly static string
ConStr=System.Configuration.ConfigurationSettings.AppS
ettings["ConStr"];
private static SqlConnection conn = new SqlConnection
(ConStr);
进行操作就行了。
 
希望你能灵活应用!
 
 
 
在项目中用程序中嵌入mdf文件的方式来进行SQLServer数据库开
发非常方便,用来发布开源项目等很方便,点击就可以运行,免
部署,特别是在教学中用起来更加方便,老师不用先将数据库文
件detach再发给学生,学生也不用将数据库文件attach。采用项
目中嵌入mdf文件的方式,老师把讲课的代码发给学生,学生打开
就可以运行。我在传智播客.net培训班教学中就是用的这种方式
进行讲解。
 
在ASP.net程序中只要将mdf文件放到项目的App_Data文件夹即可
,在连接字符串中使用
Data Source=.\SQLEXPRESS;AttachDbFilename=|
DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
做连接字符串即可。
 
但是在WinForm程序中,如果在项目的App_Data文件夹中新建一
个mdf文件,然后用
Data Source=.\SQLEXPRESS;AttachDbFilename=|
DataDirectory|\CallCenter.mdf;Integrated
Security=True;User Instance=True
进行连接会提示找不到CallCenter.mdf。原来WinForm程序并不
会去App_Data中找mdf文件。原来在ASP.net中DataDirectory的
值是当前项目的App_Data路径,而WinForm中的DataDirectory值
则是当前项目的路径,因此Winform中mdf文件不用放到App_Data
中,放到项目根目录下就可以。
 
但是新问题随之又来了,在WinForm中用这种方式开发的时候有时
候改了项目中mdf文件中的表中的数据或者表结构,运行的时候却
发现运行时通过程序读取的数据或者表结构没有变,而有时调试
时Insert插入的数据在这次调试的时候竟然没有了。经过研究发
现,WinForm程序运行的时候连接的是bin/Debug下的mdf文件,
而不是项目中的mdf文件,这是和ASP.net程序行为不同的地方。
每次程序发生Build行为的时候,项目中的mdf就会覆盖
bing/Debug下的mdf文件,也就是有两个mdf文件的存在,项目中
的mdf相当于“源文件”。虽然可以通过修改文件
的“BuildToOuput”属性来部分解决问题,但是仍然不是很完美
 
有一个比较很直接的想法,就是让程序去连接项目中的mdf文件,
而不是连接bin/Debug下那个。
经过查询资料找到了修改方法,在Program.cs文件Main函数最开
始加入如下代码:
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);
            }
 
原理简单分析:连接字符串中的DataDirectory的值就是通过
AppDomain.CurrentDomain.SetData赋值过去的,如果当前程序
的目录以"\bin\Debug\"或者"\bin\Release\"则认为它是运行在
VisualStudio环境中,就取项目的目录然后赋值给
DataDirectory这个key。既然是CurrentDomain.SetData,估计
对于非默认AppDomain中的数据库连接代码可能会不起作用(只
是猜测,没验证),这就要需要创建子AppDomain的时候再去赋
值了。
 
上面的代码还是有一点潜在的bug的,比如正式的运行的时候exe
被很杯具的放到了某个bin\Debug目录下,就会有问题,不过想
想正式生产环境运行的时候肯定不会用这种AttachDbFilename方
式,这种方式只存在于开发环境,因此也就睁一只眼闭一只眼了
,呵呵。
   
 
 
                                                       
            可能遇到的错误
1.由于启动用户实例的进程时出错,导致无法生成sql server的
用户实例
http://wenwen.soso.com/z/q15616823.htm
2.版本太低,支持2005及以下数据库。解决:安装VisualStudio
2008 sp1 server
3.启动超时,多试几次。
Console.WriteLine("请输入用户名");
string username=Console.ReadLine();
Console.WriteLine("请输入要插入的密码");
string password=Console.ReadLine();
 
4.ADo.net详解
 执行简单的Insert语句
  SqlCommand表示向服务器提交的一个命令(SQL语句等)
  CommandText属性为要执行的SQL语句,ExecuteNonQuery方法
执行一个非查询语句(Update、Insert、Delete等)
  using(SqlCommand cmd=conn.CreateCommand()){
    cmd.CommandText="Insert into T_UsersName.Password)
 values('admin','888888')";
    com.ExecuteNonQuery();
}
 
  ExecuteNonQuery返回值是执行的影响行数
  常犯错:
  string usename='text';
  ...
  cmd.CommandText="Insert into T_Users
(UserName,Password) values(username,'888888');
 
6.ADO.net详解2.avi
 
 User是关键字,表名T_开头,字段F开头。
 不要与关键字冲突。
  SqlCommand的ExecuteScalar方法用于执行查询,并返回查询
所返回的结果集中第一行的第一列,因为不能确定返回值的类型
,所以返回值是object类型。
  cmd.CommandText="select count(*) from T_Users";
  int i=Convert.ToInt32(cmd.ExecuteScalar());
  cmd.CommandText="select getdate()";
  DateTime dt=Convert.ToDateTime(cmd.ExecuteScalar());
 
  得到自动增长字段的主键值,在values关键词前面加上output
inserted.id,其中id为主键字段名,执行结果就是插入的主键值
,用ExecuteScalar执行最方便。
  cmd.CommandText="Insert into T_Users
(UserName,Password)
  output inserted.Id values('admin','888888')";
  int i=Convert.ToInt32(cmd.ExecuteScalar());
 
 
  insert into T_Users
  (UserName,Password)
   output inseted.Id
   values ('admin','888888')
 
 
执行查询
执行有多行结果集的用ExecuteReader
SqlDataReader reader=
cmd.ExecuteReader();...
while(reade.Read())
{
Console.WriteLine(Reader.GetString(1));
}
reader的getSting、GetInt32等方法只接受整数参数,
也就是序号,用GetOrdinal方法根据列名动态等到序号。
  7.ADO.NetUsing与Close.avi
 
  为什么用using.Close:关闭以后还能打开。
  Dispose:直接销毁,不能再次使用。
  using在除了作用域以后调用
Dispose,SqlConnection/FileStream等的Dispose内部都会做这
样的判断:判断有没有Close,如果没有Close就先Close 再
Dispose.
 
 
   
  class8 SQL注入漏洞攻击
登录判断:select * from T_Users where UserName=... and
Password=...,将参数拼到SQL语句中。
构造恶意的Password: ' or '1'='1
if(reader Read())
{
Console.WriteLine("登录成功");
}
else
{
Console.WriteLine("登录失败");
}
防范注入漏洞攻击的方法: 不适用SQL语句拼接,通过参数赋值
 
查询参数
SQL语句使用@UserName表示"此处用参数代替",像SQLCommand的
Parameters中添加参数
cmd.CommandText="select * from T_Users where UserName=
@UserName and Password=@Pasword",
cmd.Parameters.Add(new SqlParameter
("UserName","admin"));
cmd.Parameters.Add(new SqlParameters
("Password",password));
参数在SQLServer内部不是简单的字符串替换,SQLServer直接用
添加的值进行数据比较,因此不会有注入漏洞攻击。
class9案例登录2.avi
class10案例数据导入导出.avi
案例:
用户界面中进行登录判断(用户名的增加)。输错三次禁止登陆
,用数据库记录ErrorTimes.
连接字符串写到配置文件中。
数据导入:从文本文件导入用户信息。易错点:
Parameter的重复添加。
 
数据导出:将用户信息导出到文本文件。
 
 
9.登录案例2
 
省市选择程序,数据全部来自于数据库。
http://www.programfan.com/blog/article.asp?id=28128
 
  案例:
IP地址归属地查询。查询结果:山东移动[菏泽].打开文件
先把数据文件解压到硬盘上,然后写程序进行数据导入:扫描解
压的目录下所有的txt文件,然后依次读取每个文件,注意用上文
件名,表三列:起始号码、结束号码,运营商名称()
 
查询:select * from *** where StartNo<=No and
EndNo>=@No.
 
 
   案例:
  省市选择程序,数据全部来自数据库:
http://www.programfan.com/blog/article.asp?id=28128百
createtable中的varchar改为nvarchar,在insert语句的汉字前
面加上N(查找","替换为",N")
  ComboBox的显示值:items.Add的参数是Object类型,也就是
可以放任意数据类型的数据,可以设置DisplayMenber属性设定
显示的属性,通过SelectedItem属性取得到就是选择的条目对应
的对象。例子。疑问:取出来的是O边界冲突,怎么能传唤为对应
的类型?变量名只是"标签"
  显示的值和实际的对象不一样,在ASP.Net中也有相同的东西
  创建一个ProvinceItem类,将数据田中在这个对象中添加到
ComboBox中。
  将连接字符串写在代码中的缺点:多次重复,违反了DRY
(Don't Repeat Yourself)原则;如果要修改连接字符串就要修
改代码。将连接字符串写在App.Config中:
  添加App.config文件:添加->新建项->常规->应用程序配置文
件。App.config是.Net的通用配置文件,在ASP.Net中也能同样
使用。
  在App.config中添加connectionString段,添加一个add项,
用name属性起一个名字(比如DbConnStr),connectionString属
性指定连接字符串。
 
  在引用节点上点击右键"添加引用",找到
System.configuration.不是所有.Net中的类都能直接调用,类
所在的Assembly要被添加到项目的引用中才可以。
 ConfigurationManager.ConnectionStrings
["DbConnStr"].ConnectionString得到连接字符串。
 
  如何在部署的程序中修改配置。
 
 
14.练习手机号码归属地查询.avi
  案例:
  文件夹选择对话框FolderBrowserDialog;
  按照通配符搜索目录下的文件string[]
Directory.GetFiles(string path.string
searchPattern,SearchOption searchOption)
 
  Path.GetFileNameWithoutExtension(filename),得到文件的
文件名(不要扩展名):Path.Combine(string path1,string
path2),将两个路径合并;Path.GetExtension(string path),
得到文件的后缀;Path.GetFileName(string Path),得到文件
的文件名;Path.GetFullPath(string path):得到文件的全路
径。
  导入前先清除旧数据.
  到58.com上找手机号测试。
 
 
18.DataSet的更新.avi
  SQLHelper
  封装一个SQLHelper类方便使用,提供ExecuteDataTable
(string sql.params SqlParameter[] parameters).
ExecuteNonQuery(string sql,params SqlParameter[]
parameters)等方法。网上有微软提供的最全的SQLHelper类,是
Enterprise Libray中的一部分。
  用SQLHelper重写登录程序。
  练习:用SQLHelper重写省市选择程序、IP地址归属地查询
  new SqlParameter("e",0)的陷阱
  Sqlconnection在程序中一直保持它open可以吗?
对于数据库来说,链接是非常宝贵的资源,一定要用完了就Close
、dispose。
 
  DataSet的更新
 
  可以更新行row["Name"]="yzk"、删除行
datatable.Rows.Rwmove()、新增行datatable.NewRow().这一
切都是修改的内存中的DataSet,没有修改数据库。
  可以调用SqlDataAdapter的Update方法将对DataSet的修改提
交到数据库,Update方法有很多重载方法,可以提交整个
DataSet、DataTable或者若干DataRow.但是需要为
SqlDataAdapter提供DelectCommand、UpdateCommand、
InsertCommand才知道如何将对DataSet的修改提交到数据库,由
于这几个Command要求的格式非常苛刻,因此开发人员自己写非常
困难,可以用SqlCommandBuilder自动生成这几个Command,用法
很简单:new SqlCommandBuilder(adapter)。查看生成的
Command(没有直接赋值给SqlDataAdapter,看
SqlCommandBuilder的)。SqlCommandBuilder要求表必须有主
键。
(*)通过DataRow的RowState可以获得行的状态(删除、修改、新
增等);调用DataSet的GetChanges()方法等到变化的结果集
,降低传递的资源占用。
 
 
19.可空数据类型
 
  C#中值类型(int、Guid、bool等)是不可以为空的,int
i=null 是错误的,因此int、bool等这些类型不能表示数据库中
的"Null".因此C#提供了"可空类型"这种语法,只要在类型后加
?就构成了可空的数据类型,比如int?、bool?,这样int?
i=null 就可以了
  判断可空类型是否为空,i==null或者i.HasValue;得到可空变
量的值,int i=(int)i.Value或者int i1=i.Value.
  类型转换:不可空类型赋值给可空类型无需显式转换(一定成
功),可空类型赋值给不可空类型则需显式转换(不一定成功)
 
20.弱类型DataSet的缺点
  只能通过列名引用,dataset.Tables[0].Rows[0]["Age"],如
果写错了列名编译时不会发现错误,因此开发时必须要记着列名
 
  int age=Convert.ToInt32(dataset.Rows[0]["Age"]),取到
的字段的值是object类型,必须小心翼翼的进行类型转换,不仅
麻烦,而且容易出错。
 
  将DataSet传递给其他使用者,使用者很难识别出有哪些列可
以供使用。
 
  进行时才能知道所有列名,数据绑定麻烦,无法使用Winform
、ASP.Net的快速开发功能。
  自己动手写强类型DataSet(类型化DataSet,TypedDataSet),
创建继承自DataSet的PersonDataSet类,封装出int? Age等属性
和bool IsAgeNull等方法,向PersonDataSet中填充。
 
  VS自动生成强类型DataSet
  添加-->新建项-->数据集
  将表从服务器资源管理器拖放到DataSet中,注意拖放过程是
自动根据表结构生成强类型DataSet等类,没有把数据也拖过来,
程序还是连那个数据库,自动将数据库链接字符串写在了
App.Config中。
  代码中使用DataSet示例:CC.RecordTableAdapter
adapter=new CC RecordTableAdapter();如何得知Adapter的类
名?选中DataSet中下半部分的Adapter,Name属性就是类名。需
要右键点击类名-->解析取得所有的数据:Adapter.GetData(),
例子程序:遍历显示所有数据,i<adapter.GetData
().Count;adapter.GetData()[i].Age.
  常见问题:类名敲不对,表名+TableAdapter,表名
+DataTable,表名+Row,然后用"解析“来填充类名,别照着我的
代码敲。
  常见问题:类的内部定义的类要通过包含namespace的全名来
引用,不能省略。类的内部定义的类就能避免同一个namespace
下类不能重名的问题。
23.类型化DataSet修改的更新.avi
 
  更新DataSet
  调用Adapter的Update方法就可以将DataSet的改变保存到数据
库。adapter.Update(datatable)
  要调用Update方法更新必须设置数据库主键,后面的Delete也
是如此。
  常见错误:"当传递具有已修改行的DataRow集合时,更新要求
有效的UpdateCommand",要为表设置主键"谁都变了,唯有主键不
会变",程序要通过主键来定位要更新的行。忘了设定主键怎么办
?先到数据库中设置主键,然后在DataSet的对应DataTable上点
右键,选择“配置”,在对话框中点击【完成】。好习惯:所有
表都要设置主键!!!看看为什么会自动帮我们GetData、
Update、Delete。
 
25.DataSet添加自定义SQL语句。avi
 
增加新的SQL语句
设计器的Adapter中点右键,选择"添加查询"-->"使用SQL语句",
就可以添加多种类型的SQL语句。如果是"SELECT(返回行)”则
SQL语句的列必须是对应DataSet类的父集合,生成两个方法:
FillBy*和GetBy*,方法名根据查询语句的意义定,比如
FillByAge,FillBy是将结果填充到现有DataSet,GetBy是将结果
以DataSet方式返回,建议两个都生成,方便以后用。看看默认生
成的GetData就明白了GetDataById、IncAge。
  "SELECT(返回单个值)"就是ExecuteScalar
  对于增加的SQL语句在代码中是以方法的形式使用的。方法的参
数类型、顺序就是VS猜测的,如果不正确或者需要调整只要选中
对应的语句,然后在[属性】窗口中修改Parameters属性即可
  增加新的SQL语句本质论,探寻源码:不能并发调用。
  像使用普通类的方法一样使用Adapter.SQL语句不用再写在界
面代码中。这就是一种数据访问层(DAL:Data Access Layer)
 
 
26.类型化DataSet案例:登录程序.avi
  TypeDataSet练习:
  用类型化DataSet重写登录、数据导入、手机号码归属地查询
、省市选择等程序。

 

 

转载于:https://www.cnblogs.com/fanhongshuo/p/3812292.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值