一、准备工作
1、数据库模型:
如你所见,EF模型是上图中三个表,第四个则是数据库视图。
2、数据:
先在HeadAddress表中插入三条数据,再在EndAddress表中也插入三条数据,最后往Customer表中插入三万条随机数据作为测试数据。
二、效率比较
1、视图 vs 跨表:遍历所有用户信息(HeadAddress、EndAddress、Customer中的字段)
2 var temp = _DataContext.CustomerView.ToList();
3 foreach (var item in temp) ;
4 // 跨表(ToList)
5 var temp = _DataContext.CustomerSet.Select(c => new
6 {
7 Name = c.Name,
8 Sex = c.Sex,
9 Street = c.EndAddress.Street,
10 Number = c.EndAddress.Number,
11 Province = c.EndAddress.HeadAddress.Province,
12 City = c.EndAddress.HeadAddress.City,
13 County = c.EndAddress.HeadAddress.County
14 }).ToList();
15 foreach (var item in temp) ;
结果:
在接下来的所有统计中,我都没有把第1次(即上图中的0次)的时间算在平均时间内(因为EF第一次访问有初始时间)。可见使用视图做遍历效果并没有提升,但是当我把测试代码改为:
2 var temp = _DataContext.CustomerView.ToList();
3 foreach (var item in temp) ;
4 // 跨表(ToList)
5 var temp = _DataContext.CustomerSet.Select(c => new
6 {
7 Name = c.Name,
8 Sex = c.Sex,
9 Street = c.EndAddress.Street,
10 Number = c.EndAddress.Number,
11 Province = c.EndAddress.HeadAddress.Province,
12 City = c.EndAddress.HeadAddress.City,
13 County = c.EndAddress.HeadAddress.County
14 }).ToList();
时,我发现效率发生了明显改变:
我们看到,视图ToList所用时间与上次相比几乎一致,甚至还有缩短,而使用跨表查找然后ToList耗时大大增加。至于原因,我认为可能是视图的ToList结果在数据结构内部为我们节省了非常多的工作。
2、视图 vs 跨表:遍历省份是“湖北”的用户信息(HeadAddress、EndAddress、Customer中的字段)
2 var temp = _DataContext.CustomerView.Where(c => c.Province == "湖北");
3 foreach (var item in temp) ;
4 // 跨表
5 var temp = _DataContext.CustomerSet.Where(c => c.EndAddress.HeadAddress.Province == "湖北")
6 .Select(c => new
7 {
8 Name = c.Name,
9 Sex = c.Sex,
10 Street = c.EndAddress.Street,
刚开始学习C#开发项目时,长期会为了写一个安全的高效的数据库连接发愁。我发现现在很多刚开始学习的朋友和有些做了一两年的朋友,也有点犯愁,我就贴上这个代码,给自己以后做个参考,也给朋友做个学习的参考。
我主要在这里统计了.NET项目下常用的数据库连接字符串:SQLServer、Oracle、Access三种数据库(MySql、SQLLite、Excel、HTML Table等等暂不列入)。
1.常用连接字符串参数说明
如需查看详细说明请参见:
SqlConnection.Connectionstring
OracleConnection.ConnectionString
OleDbConnection.ConnectionString
如果主数据文件为只读,则附加操作将失败。
该路经可以是绝对路径,也可以是相对路径,这取决于是否使用 DataDirectory 替换字符串。如果使用 DataDirectory,则对应的数据库文件必须存在于替换字符串指向的目录的子目录中。
备注:远程服务器、HTTP 及 UNC 路径名不受支持。
实例:必须按照如下方式使用关键字“database”(或其别名之一)指定数据库名称:
"AttachDbFileName=|DataDirectory|\data\YourDB.mdf;integrated security=true;database=YourDatabase"
如果数据文件所在的目录中存在日志文件,并且在附加主数据文件时使用了“database”关键字,则会生成错误。这种情况下,请移除日志文件。附加了数据库后,系统将根据物理路径自动生成一个新的日志文件。 Integrated Security 或 Trusted_Connection 'false'当为 false 时,将在连接中指定用户 ID 和密码。当为 true 时,将使用当前的 Windows 帐户凭据进行身份验证。可识别的值为 true、false、yes、no 以及与 true 等效的 sspi(强烈推荐)。
2.常用连接字符串实例
如需查看更多实例请参见:各种连接字符串实例
Server=服务器地址;Database=数据库名称;User Id=用户名;Password=密码;
SQLServer本地文件可信连接:
Server=.\SQLExpress;AttachDbFilename=|DataDirectory|mydbfile.mdf;Database=数据库名称;Trusted_Connection=sspi;
SqlServer自定义连接:
Data Source=(LOCAL);Initial Catalog=数据库名称;User ID=用户名;Password=密码;Persist Security Info=True;Enlist=true;Max Pool Size=300;Min Pool Size=0;Connection Lifetime=300;Packet Size=1000;
Oracle简易连接:
Data Source=orclsid_127.0.0.1;User Id=用户名;Password=密码;
//这个数据源是从Oracle的安装目录下tnsnames.ora文件中去找的。而并非是在系统的“管理工具”下的“数据源(ODBC)”中找。这个tnsnames.ora文件是在Oracle的安装目下的“client_1/network/admin/”下。
Oracle自定义连接:
Server=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=服务器地址)(PORT=端口号)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=数据库名称)));User Id=用户名;Password=密码;Persist Security Info=True;Enlist=true;Max Pool Size=300;Min Pool Size=0;Connection Lifetime=300;
Access简易连接:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=用户名;Password=密码;
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;Jet OLEDB:Database Password=密码;
我仅罗列出了一些常用的连接字符串实例和参数说明。我原本是准备根据每种数据库来分别详细的阐述连接字符串的实例和参数说明,后来没有这么做,因为这篇帖子主要是为了满足刚开始学习的朋友的需求,因为基本能适应大部分项目需要了。如果是需求,并发数很高的项目,则需要自行对项目、数据库、服务器等等进行优化和改造,在这里就不详细阐述了。
本文链接
通过一个委托调用多个方法可能导致一个大问题,多播委托包含一个逐个调用的委托集合,如果通过委托调用的其中一个方法抛出一个异常,整个迭代就会停止
示例如下:
{
Console.WriteLine("One");
throw new Exception(" Error in one");
}
static void Two()
{
Console.WriteLine("Two");
}
Action d1 = One;
d1 += Two;
try
{
d1();
}
catch (Exception)
{
Console.WriteLine("Exception caught");
}
委托只调用了第一个方法,因为第一个方法抛出了一个异常,所以委托的迭代会停止,不再调用Two()方法,结果:
One
Exception caught
为了避免这个问题,应自己迭代方法列表,Delegate类定义的GetInvocationList()方法,它返回一个Delegate对象数组,现在可以使用这个委托调用与委托直接相关的方法,
捕获异常,并继续下一次迭代
d1 += Two;
Delegate[] delegates = d1.GetInvocationList();
foreach (Action item in delegates)
{
try
{
item();
}
catch (Exception)
{
Console.WriteLine("Exception caught");
}
}
结果如下:
One
Exception caught
Two
本文链接