All posts by 龙生
微软企业库5.0 学习之路——第二步、使用VS2010+Data Access模块建立多数据库项目
在通过上一篇文章:[EntLib]微软企业库5.0 学习之路——第一步、基本入门 对EntLib5.0的相关知识进行了了解,并通过微软给出的学习例子我们可以了解企业库的各模块的基本用法(由于园子里的好几位兄弟都已经把企业库的各模块的使用都介绍过了,所以我这边就不进行具体功能的介绍,我写的学习之路是以企业库如何在一个项目中的使用为基础来介绍,以一个简单的学生信息管理系统项目为基础,如何使用企业库来对这个项目进行开发、优化)。 (本文内容比较简单,高手们可以直接忽略不看了,仅仅就是数据库访问操作和工厂分层) 现在我就开始进入学习之路的第二步——Data Access模块,这个模块是企业库中被使用频率最高的模块,它很好的封装了数据库操作应用,为我们进行多数据库系统开发提供了便利,只需更改配置文件就可以很快的切换数据库访问(可惜还是要重写SQL语句,没法和ORM比)。 下面是我在配置企业库的时候碰到问题,如果没有碰到可以略去不看(可能有点小白) 注意:此处切换数据库配置必须是计算机中已经安装好相应的数据库访问模块,如需要进行从MS SQL向SQLite数据库的变更时,计算机中必须安装好SQLite数据库访问模块(在这里我就碰到了这个问题,原来我机器上在VS2008开发时已经安装过SQLite数据库访问模块,但是新装了VS2010,在VS2010引用对话框中也能访问到在VS2008安装的SQLite(但是在企业库5.0配置器中无法查看到SQLite),但是发现更改企业库的配置文件后无法访问SQLite数据库,尝试了很多方法都没用,结果死马当活马医又重新装了一遍SQLite数据库访问模块再重新打开企业库配置器就可以看到SQLite数据库了(所以请确保在企业库编辑器中可以查看到要切换的数据库,否则可能导致无法访问数据库)。看下图: 回归正题,这次的学习由于VS2010发布了,而且企业库5.0也都支持.NET4.0,所以决定企业库的学习之路采用VS2010进行学习(顺便熟悉下.NET4的特性,毕竟公司的项目不可能立马转移到.NET4.0的,现在就当练手吧) 好了,现在就开始进行第2步的学习了,首先看下项目的结构: 项目采用仿MS PetShop架构,如不了解此架构可以到此查看了解:PetShop的系统架构设计 其中DAL和DALSQLite层对应MS SQL和SQLite数据库,Helper为整个项目的帮助器 现在来具体了解下DAL层 在DAL层中引用了Helper,IDAL,EnterpriseLibrary.Common和EnterpriseLibrary.Data这4个项目,其中Helper项目中有个DBHelper.cs,用于获取当前的数据对象,其代码如下(采用了C#4.0的语法特性,默认参数,数据库对象名默认为空,这样则会调用企业库默认的数据库对象,同时也可以在调用的时候赋值,这样则根据传递过来的数据库对象名来创建数据库,通过这个参数我们将原来需要重载的2个方法才能实现合并成了一个方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Data; namespace EntLibStudy.Helper { public static class DBHelper { /// <summary> /// 获取数据库对象 /// </summary> /// <param name="name">数据库实例名(默认name为空,调用默认数据库实例)</param> /// <returns>数据库对象</returns> public static Database CreateDataBase(string name = "") { //return DatabaseFactory.CreateDatabase(name); return EnterpriseLibraryContainer.Current.GetInstance<Database>(name); } } } |
在DAL层中则引用Helper来获取数据库对象,进行数据库操作,我们现在来看下具体的数据库访问类编写代码,学员操作类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Text; using Microsoft.Practices.EnterpriseLibrary.Data; using EntLibStudy.Model; using EntLibStudy.Helper; namespace EntLibStudy.DAL { public class StudentService : EntLibStudy.IDAL.IStudentService { /// <summary> /// 新增学生 /// </summary> /// <param name="student">学生对象</param> /// <returns></returns> public int Add(Student student) { Database db = DBHelper.CreateDataBase(); StringBuilder sb = new StringBuilder(); sb.Append("insert into Student values(@ClassId,@SID,@Password,@Name,@Sex,@Birthday,@IsAdmin);SELECT @@IDENTITY;"); DbCommand cmd = db.GetSqlStringCommand(sb.ToString()); db.AddInParameter(cmd, "@ClassId", DbType.String, student.ClassId); db.AddInParameter(cmd, "@SID", DbType.String, student.Sid); db.AddInParameter(cmd, "@Password", DbType.String, student.Password); db.AddInParameter(cmd, "@Name", DbType.String, student.Name); db.AddInParameter(cmd, "@Sex", DbType.Int32, student.Sex); db.AddInParameter(cmd, "@Birthday", DbType.DateTime, student.Birthday); db.AddInParameter(cmd, "@IsAdmin", DbType.Int32, student.IsAdmin); int id = Convert.ToInt32(db.ExecuteScalar(cmd)); return id; } /// <summary> /// 更新 /// </summary> /// <param name="classInfo">学生对象</param> /// <returns>是否成功</returns> public bool Update(Student student) { Database db = DBHelper.CreateDataBase(); StringBuilder sb = new StringBuilder(); sb.Append("update Student set ClassId=@ClassId,"); sb.Append("SID=@SID,"); sb.Append("Password=@Password,"); sb.Append("Name=@Name,"); sb.Append("Sex=@Sex,"); sb.Append("Birthday=@Birthday,"); sb.Append("IsAdmin=@IsAdmin "); sb.Append(" where ID=@ID"); DbCommand cmd = db.GetSqlStringCommand(sb.ToString()); db.AddInParameter(cmd, "@ClassId", DbType.String, student.ClassId); db.AddInParameter(cmd, "@SID", DbType.String, student.Sid); db.AddInParameter(cmd, "@Password", DbType.String, student.Password); db.AddInParameter(cmd, "@Name", DbType.String, student.Name); db.AddInParameter(cmd, "@Sex", DbType.Int32, student.Sex); db.AddInParameter(cmd, "@Birthday", DbType.DateTime, student.Birthday); db.AddInParameter(cmd, "@IsAdmin", DbType.Int32, student.IsAdmin); db.AddInParameter(cmd, "@ID", DbType.Int32, student.Id); return db.ExecuteNonQuery(cmd) > 0 ? true : false; } /// <summary> /// 删除 /// </summary> /// <param name="id">学生ID</param> /// <returns>是否成功</returns> public bool Delete(int id) { Database db = DBHelper.CreateDataBase(); StringBuilder sb = new StringBuilder(); sb.Append("delete from Student "); sb.Append(" where ID=@ID"); DbCommand cmd = db.GetSqlStringCommand(sb.ToString()); db.AddInParameter(cmd, "@ID", DbType.Int32, id); return db.ExecuteNonQuery(cmd) > 0 ? true : false; } /// <summary> /// 根据学生ID查询学生对象 /// </summary> /// <param name="id">学生ID</param> /// <returns></returns> public Student SelectById(int id) { Student student = null; Database db = DBHelper.CreateDataBase(); StringBuilder sb = new StringBuilder(); sb.Append("select * from Student "); sb.Append(" where ID=@ID"); DbCommand cmd = db.GetSqlStringCommand(sb.ToString()); db.AddInParameter(cmd, "@ID", DbType.Int32, id); using (IDataReader reader = db.ExecuteReader(cmd)) { if (reader.Read()) { student = new Student() { Id = reader.GetInt32(0), ClassId = reader.GetInt32(1), Sid = reader.GetString(2), Password = reader.GetString(3), Name = reader.GetString(4), Sex = reader.GetInt32(5), Birthday = reader.GetDateTime(6), IsAdmin = reader.GetInt32(7) }; } } return student; } /// <summary> /// 查询所有学生信息 /// </summary> /// <returns></returns> public IList<Student> SelectAll() { List<Student> list = new List<Student>(); Database db = DBHelper.CreateDataBase(); StringBuilder sb = new StringBuilder(); sb.Append("select * from Student "); DbCommand cmd = db.GetSqlStringCommand(sb.ToString()); using (IDataReader reader = db.ExecuteReader(cmd)) { while (reader.Read()) { list.Add(new Student() { Id = reader.GetInt32(0), ClassId = reader.GetInt32(1), Sid = reader.GetString(2), Password = reader.GetString(3), Name = reader.GetString(4), Sex = reader.GetInt32(5), Birthday = reader.GetDateTime(6), IsAdmin = reader.GetInt32(7) }); } } return list; } /// <summary> /// 查询所有学生信息 /// </summary> /// <returns></returns> public IList<Student> SelectAllMapper() { var list = new List<Student>(); Database db = DBHelper.CreateDataBase(); DataAccessor<Student> studentAccessor; //studentAccessor = db.CreateSqlStringAccessor("select * from Student", // MapBuilder<Student>.MapAllProperties(). // Build() // ); studentAccessor = db.CreateSqlStringAccessor("select * from Student", MapBuilder<Student>.MapAllProperties(). Map(p => p.Id).ToColumn("ID"). Map(p => p.Sid).ToColumn("SID"). Map(p => p.Password).WithFunc(f => "******").//将密码转换为"*",无法直接查看 Map(p => p.Name).WithFunc(ToUpperName).//将学员名称转换为大写 Map(p => p.Sex).ToColumn("Sex"). Map(p => p.Birthday).ToColumn("Birthday"). Build() ); list = studentAccessor.Execute().ToList(); return list; } /// <summary> /// 将学员名称转换为大写 /// </summary> /// <param name="dataRecord"></param> /// <returns></returns> private string ToUpperName(IDataRecord dataRecord) { var name = (string)dataRecord["Name"]; return name.ToUpper(); } public Student SelectBySid(string sid) { Student student = null; Database db = DBHelper.CreateDataBase(); StringBuilder sb = new StringBuilder(); sb.Append("select * from Student "); sb.Append(" where SID=@SID"); DbCommand cmd = db.GetSqlStringCommand(sb.ToString()); db.AddInParameter(cmd, "@SID", DbType.String, sid); using (IDataReader reader = db.ExecuteReader(cmd)) { if (reader.Read()) { student = new Student() { Id = reader.GetInt32(0), ClassId = reader.GetInt32(1), Sid = reader.GetString(2), Password = reader.GetString(3), Name = reader.GetString(4), Sex = reader.GetInt32(5), Birthday = reader.GetDateTime(6), IsAdmin = reader.GetInt32(7) }; } } return student; } } } |
其中的代码都是采用了比较常见的老套路: 1、获取数据库对象 2、构建Command对象并进行执行语句及参数赋值 3、通过数据库对象调用相应方法执行Command 企业库在Data Access上帮我们做了比较好的封装,相当于为我们提供了如SQLHelper,OracleHelper类,只不过这个帮助类转换了一个个数据库的对象,通过数据库对象来对数据库数据进行操作 (个人认为通过这种方式进行操作更加直观,而且企业库的对SQL语句的参数操作方法也很直观:AddInParameter,AddOutParameter,GetParameterValue很好的区分了参数的操作,比原来的SQLCommand好多了) 如果仔细看了上面操作代码的朋友肯定发现了类中有个叫SelectAllMapper的方法,这个方法采用的是企业库5.0中新提供的Accessor进行RowMapper来直接为实体赋值,相比原来的使用reader方式取值赋值更加优雅,只要SQL查询出来的对象字段和实体对象属性一样就可以使用MapAllProperties()方法直接赋值,如果不同的话可以使用map方法来对个别属性单独映射,而且在映射的时候还可以使用WithFunc来进行进一步操作,在代码中我将密码进行了替换,以“*”的形式展示,同时把学员的名称以大写的形式展示。 (注:更多的企业库Data Access模块方法使用可以点击这里下载微软给出的学习例子和http://www.entlib.com/发布的学习手册) 在完成底层的操作,现在我们就开始对企业库的数据库访问进行配置: 在Web层的Web.config上右键打开企业库配置器:Blocks-Add Data Settings-Add DataBase Connstring,新建2个数据库对象,一个是MS SqlServer数据库,一个是SQLite数据库. 新建一个数据库设置 新建二个数据库连接 一个为EntLibStudy,另一个为EntLibSQLite 我们来看下具体的配置文件代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<configuration> <configSections> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> </configSections> <dataConfiguration defaultDatabase="EntLibStudy" /> <connectionStrings> <add name="EntLibStudy" connectionString="server=VOLK\SQL2005;database=EntLibStudy;Integrated Security=True;" providerName="System.Data.SqlClient" /> <add name="EntLibStudySQLite" connectionString="data source=|DataDirectory|EntLibStudySQLite.db3" providerName="System.Data.SQLite" /> </connectionStrings> <appSettings> <add key="DAL" value="EntLibStudy.DAL" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0" > <expressionBuilders> <add expressionPrefix="RouteUrl" type="System.Web.Compilation.RouteUrlExpressionBuilder"/> <add expressionPrefix="RouteValue" type="System.Web.Compilation.RouteValueExpressionBuilder"/> </expressionBuilders> </compilation> <authentication mode="Forms"> </authentication> </system.web> </configuration> |
至此我们就完成了Data Access模块的代码编写和基本设置(具体代码请到文章底部下载源代码,类似代码则不再描述)。 这时如果项目需求发生了变更,由于成本太高不能使用MS SQL SERVER,而要改用SQLite数据库时则只需更改配置文件,将dataConfiguration配置节中defaultDatabase更改为EntLibStudySQLite,将appSettings配置节中DAL的值改为EntLibStudy.DALSQLite即可立刻切换到SQLite数据库。 下面我来看下运行出来的效果: 红色框中地址采用了ASP.NET4中的路由功能,实现了地址重写 红框中如上面的分析,在DAL层进行属性映射的时候已经将密码以*代替,学员姓名以大写形式展现(此页面仅用来展示属性映射,无其他用处,页面地址为:~/Student/StudentList.aspx) 至此,学习之路的第二步——Data Access模块的学习就到此为止了,其他一些东西请下载源代码查看。 注意: 1、MSSQL数据库在DataBase目录下(需要自行附加数据库),SQLite数据库在Web目录的App_Data下,由于考虑到项目的大小,所以每个项目的BIN目录都已经删除,如出现无法生成项目请自行添加相关企业库的DLL。 2、由于微软企业库5.0 学习之路这个系列我是准备以一个小型项目的形式介绍企业库的各模块,所以源代码会根据系列文章的更新而更新,所以源代码不能保证与文章中所贴代码相同。 3、项目开发环境为:VS2010+SQL2005。 4、管理员帐户:admin 密码:admin 项目下载地址:点我下载 转自:http://www.cnblogs.com/kyo-yo/archive/2010/06/10/Learning-EntLib-Second.html
View Details微软企业库5.0 学习之路——第一步、基本入门
话说在大学的时候帮老师做项目的时候就已经接触过企业库了但是当初一直没明白为什么要用这个,只觉得好麻烦啊,竟然有那么多的乱七八糟的配置(原来我不知道有配置工具可以进行配置,请原谅我的小白)。 直到去年在做项目的时候在看代码生成工具的时候看到了许多生成工具都内置了企业库的数据库访问及一些相关模块,才突然顿悟了,可能企业库应该还是有点用的,于是就试着使用了企业库的一些模块(当时版本是4.1),果然觉得企业库还是很不错的,微软在企业库中为我们封装了许多日常经常使用的模块,如:数据库访问,缓存,日志,异常处理,加密,IOC等等,在日常的项目开发中,企业库已经贯穿了一个项目从底层到表示层基本上需要用到的模块,大大方便了我们的开发,毕竟自己再重复造轮子还不如就用微软的(毕竟企业库现在都到5.0) 最近在看园子里有好几位都在写,如:virus,huangcong。我现在写的其实基本上都是自己的学习之路(可能没前面2位写的好,但就当自己的学习笔记吧)。 废话不多说了,首先开始学习企业库的基本概念,一下摘自sfbirp的企业库学习笔记: 一、什么是企业库? 企业库包含一系列应用程序模块和核心架构。这些高复用的组件旨在帮助开发者解决一些共同的企业开发问题。 企业库同时提供高可配置的特性,使我们管理重复的工作更加容易,例如我们知道的在应用的很多地方发生的横切关注点。包括像日志记录、缓存、异常管理等。另外,它提供的依赖注入容器能够简化和分解你的设计,使他们更加可实验和容易理解,帮助你创建更加高性能的设计和各种应用。 二、使用企业库的3个简单步骤: 1.引用和配置你需要的程序集。 2.通过企业库配置应用。 3.在你的代码中创建和使用企业库对象。 三、企业库的好处: 应用模块帮助解决开发者从一个项目到另一个项目面对的共同问题。他们的设计封装了微软推荐的做法,这些都是基于微软框架的应用开发。例如,数据访问应用模块提供了对ADO.NET访问最频繁使用的特征。在某些情况下,应用模块还添加了一些基础类库没有直接提供的相关功能。 四、企业库的目标: 1.一致。所有的企业库模块都坚持一致的设计模式和实现方式。 2.可扩展性。所有的应用模块包括定义扩展点,允许开发人员通过添加自己的代码定制应用模块的行为。 3.易用性。企业库提供了许多实用性的东西,包括一个图形化配置工具,简单的安装过程,完成的文档和示例。 4.集成。企业库应用模块被设计得能够一起很好的工作,并且也被这样测试过。但是你不必一起使用他们。我们可以单独使用这些应用模块,同时这些应用模块之间也有些依赖,比如在企业库核心和Unity中的一些通用组件。 上面是企业库的基本概念,理解了企业库的相关知识后,我们可以开始来安装企业库了 1、下载地址:点我进入下载页面(不是直接下载),安装后就可以使用了。 这次5.0相比4.1的最大改动就是整个配置工具采用了WPF重新构建和实例化和管理对象生命周期的全依赖注入的实现,同时支持VS2008SP1和VS2010,话说虽然这次的配置工具变化挺大的,但是一旦熟悉了就觉得比4.1的好,因为可以清楚的看见每个模块的之间的依赖关系。 附相关改动,还是摘自sfbirp的企业库学习笔记: 一、Unity和对象生成器的整合 在这个版本中,用于创建对象的基本技术是一个单一的依赖注入容器,默认的是Unity。你可以使用容器生成企业库对象的实例并注入到其他的对象。 企业库提供一个标准的接口从Unity容器中来获得定义在企业库配置中的对象的实例,如SqlDatabase或LogWriter.另外,注入友好的实例门面处理静态门面之外是有效的,因为静态门面不能用注入,但是为了向后兼容以前的版本而存在。在本版本中的示例中都是用依赖注入,但是以前版本中是用的静态工厂类和静态门面在这个版本中还是支持的。对象生成器,一个低版本的依赖注入机制在这个版本中被归入Unity中,在项目中不再需要单独引用对象生成器集。 支持Unity容器,必须引用一个被包含在企业库中的Microsoft.Practices.ServiceLocation程序集。如果要使用一个第3方的依赖注入容器,必须直接实现IServiceLocator接口或者通过适配器实现。 二、影响所有模块的变化: 1.在企业库中主要修正是使用依赖注入机制。所用的应用模块以及核心系统都是用依赖注入机制,并使用Unity作为默认的依赖注入容器,来创建和管理企业库对象。 2.自主容器的实现通过实现Common Service Locator项目提供的 IServiceLocator 接口来完成。 3.由于错误配置引发的错误将提供更多有用的错误信息。 4.配置系统公开了一个 fluent接口,用来为单个对象或整个应用创建和填充配置源。fluent API使得为各种情景创建配置源更加容易。 5.ConfigurationView类被删除. 6.一些配置元素有默认值,可能不同于以前版本的隐式默认值. 7.企业库现在允许你通过另一个配置文件合成一个混合配置文件. 8.可以可通过不同的配置文件读取不同的配置信息. 9.企业库不支持XAML浏览器应用程序(XBAP). 10.WmiEnabled标志为了像前兼容仍然存在企业库中,但是在5.0中是被忽略的,而且将来会被删除. 11.改进式的安装允许你只安装部分应用模块及配置工具. 12.在以前版本中要做统一集成,必须添加核心企业库的扩展和每个模块的扩展。现在如果你只需要直接访问容器,那么只有核心扩展是必须的。单独模块将自动支持。 旧的功能为了保持像前兼容仍然保留,但已经不起作用。 13.FileConfigurationSource.Save 的签名已经改变,参数由3个变为2个。 14.快速入门不再包含在主安装程序中。 三、Breaking变化: 1.企业库现在抛出了一个配置错误ActivationException,之前是System.Configuration.ConfigurationErrorsException。这包括试着解决没有配置信息错误的一个实例提供者。 2.以前版本在获取应用模块错误时抛出BuildFailedException错误,现在对于所有的应用模块都抛出ActivationException 3 .之前的版本,在讲一个空源传到容器来调用容器的时候,会抛出ArgumentNullException,现在抛出NullReferenceException 4.ObjectBuilder2不再是一个单独的程序集,而是集成到了Unity集合中,在项目中也不需要引用ObjectBuilder2.dll。 5.WMI支持已经从企业库中删除,除了在logging模块中的WMI跟踪监听器。 6.如果你没有关闭DbDataReader,可能会导致随机的、很难在您的代码中找到的错误,尤其是当你正在一个由TransactionScope上下文创建的隐式事务下操作时。 你必须始终确保您的应用程序及时关闭DbDataReader,无论是明确的DbDataReader.Close方法关闭或是逼迫DbDataReader释放。 7.如果你使用 validator 特性必须引用 System.ComponentModel.DataAnnotations程序集。 8.为FileConfigurationSource.Save方法签名已更改。该方法有两个参数,而不是3个参数 9.Microsoft.Practices.EnterpriseLibrary.Configuration.Design.dll集合的功能和其他设计时集合被一个新的集合Microsoft.Practices.EnterpriseLibrary.Configuration.DesignTime.dll代替。 10,性能计数器异常从PolicyInjection.CallHandlers移到 PolicyInjection 程序集。 11.包含在Policy Injection Application Block中的CachingCallHandler有未处理的安全漏洞,已经从Policy Injection Application Block中移除。 四、配置工具的改变: 1.新的企业拥有一个新的GUI库和一个元数据驱动的可扩展性模。 2.支持向导 3.新的类型选择。 4.不支持对依赖策略的Environmental Overrides 。日志模块处理Categories。 五、缓存模块变化: 1.缓存清除已被完全重写的性能优化 六、数据库访问模块: 1.ExecuteReader, ExecuteXmlReader, ExecuteScalar, and ExecuteNonQuery方法具有异步版本。 2.包含了很多新的方法和类允许你提取数据作为对象序列。例如在合适的时候使用客户端查询技术,如LINQ. 3.存在的方法ExecuteReader和新的方法BeginExecuteReader不接收CommandBehavior 参数。默认的当调用这些方法的时候这些方法 会自动设置CommandBehavior 属性到reder中用来关闭连接直到指定一个事务。 七、异常处理模块: 1.日志异常处理重新使用日志模块的Log Writer and Trace Listeners 。这在之前版本中不是默认设置。 2.增加一个功能,通过ExceptionManager.Process 方法接收一个默认值并返回一个值。 在安装完企业库同时知道了5.0的变化后,就开始正式的学习了,学习的最好办法不是看企业库的源代码(我是看不懂),而是下载微软发布的学习例子 学习例子下载地址:点我进入下载页面(不是直接下载) 这个学习例子里面已经包含了所需的类库及代码演示(C#和VB.NET都有),同时可以右键例子中的App.config来看下例子中的模块是怎么配置的。 同时,在学习例子的时候可以看下由http://www.entlib.com/发布的中文学习手册,虽然是4.1的,但是里面的所有内容都和5.0的例子一样(5.0只不过是重新实现了1遍),把例子和文档结合起来看学习起来就快了很多了: 中文学习手册:点我下载 Entlib5程序:点我进入下载页面(不是直接下载), 到此,Entlib5的学习之路的第一步就结束了,基本上通过微软发布的学习例子和对应的中文学习手册可以对5.0的使用已经有了个基本的了解。 转自:http://www.cnblogs.com/kyo-yo/archive/2010/06/07/Study-Entlib5-First.html
View DetailsADO.NET Entity Framework 学习(2)
ADO.NET Entity Framework,即下一代的ADO.NET。它是比Linq To SQL更加强大的ORM,让开发人员只需要着眼于领域对象模型的开发,而不需要考虑它们是如何与关系数据库交互。上一篇文章简单介绍了在项目中如何使用ADO.NET实体框架,从现在开始,正式进入了ADO.NET的学习之旅。这篇文章主要介绍在ADO.NET实体框架中如何进行查询(以Northwind数据库为例)。 1. 使用EntityCommand进行查询 在实体框架中,我们可以通过EntityCommand进行查询,它的使用方法就像ADO.NET中的SqlCommand。不同的是SqlCommand使用标准SQL语句对数据库进行查询,而EntityCommand使用Entity SQL对EntityContainer进行查询,当然最终实体框架会将Entity SQL转换成标准SQL语句查询数据库。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span style="color: #2b91af;">EntityConnection</span> con = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">EntityConnection</span>(<span style="color: #a31515;">"Name=NorthwindEntities"</span>); con.Open(); <span style="color: #0000ff;">using</span> (<span style="color: #2b91af;">EntityCommand</span> cmd = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">EntityCommand</span>(<span style="color: #a31515;">"select value c from NorthwindEntities.Customers as c"</span>, con)) { <span style="color: #2b91af;">EntityDataReader</span> reader = cmd.ExecuteReader(<span style="color: #2b91af;">CommandBehavior</span>.SequentialAccess); <span style="color: #0000ff;">while</span> (reader.Read()) { <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"ID [{0}], ContactTitle [{1}]"</span>, reader[<span style="color: #a31515;">"CustomerID"</span>], reader[<span style="color: #a31515;">"ContactTitle"</span>]); } } |
首先是建立一个EntityConnection,它接受一个参数,表明使用的是在config文件中的哪个连接字符串。 <connectionStrings> <add name="NorthwindEntities" connectionString="metadata=.\Northwind.csdl|.\Northwind.ssdl|.\Northwind.msl;provider=System.Data.SqlClient;provider connection string="Data Source=localhost\sqlexpress;Initial Catalog=Northwind;Integrated Security=True"" providerName="System.Data.EntityClient" /> </connectionStrings> 可以看到这个连接字符串和以往ADO.NET中使用的连接字符串并不一样。metadata:指明.csdl/.ssdl/.msl三个文件的路径,这三个文件的作用以后再做说明。provider:表示使用的是SqlClient或者Oledb或者Odbc。provider connection string:这一项便是以往所用的连接字符串。providerName表示现在用的是EntityClient。 接着构造EntityCommand,最后通过EntityDataReader进行数据的读取,值得注意的是这里的EntityCommand接受的是Entity SQL语句,而不是标准SQL语句,具体的Entity SQL语法可以参考帮助文档。 2. 使用ObjectQuery进行查询 实体框架提供一个名为ObjectQuery的类,它让开发人员通过Entity SQL进行查询,查询结果以对象的形式供使用。
1 2 3 4 5 6 7 8 9 10 11 |
<span style="color: #0000ff;">using</span> (<span style="color: #2b91af;">NorthwindEntities</span> ctx = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">NorthwindEntities</span>()) { <span style="color: #2b91af;">ObjectQuery</span><<span style="color: #2b91af;">Customer</span>> query = ctx.CreateQuery<<span style="color: #2b91af;">Customer</span>>(<span style="color: #a31515;">"NorthwindEntities.Customers"</span>); <span style="color: #2b91af;">ObjectResult</span><<span style="color: #2b91af;">Customer</span>> result = query.Execute(<span style="color: #2b91af;">MergeOption</span>.NoTracking); <span style="color: #0000ff;">foreach</span> (<span style="color: #2b91af;">Customer</span> c <span style="color: #0000ff;">in</span> result) { <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"ID [{0}], ContactTitle [{1}]"</span>, c.CustomerID, c.ContactTitle); } } |
首先调用CreateQuery方法来创建ObjectQuery对象(当然这里也可以使用new,只是传进的参数不同而已),它接受Entity SQL语句作为参数。然后调用Execute方法进行查询,它接受MergeOption枚举型的参数,表示解决冲突的方法。查询结果以对象的形式(这里是Customer)保存在ObjectResult中。 下面是使用new的写法:
1 2 3 4 5 6 7 8 9 10 |
<span style="color: #0000ff;">using</span> (<span style="color: #2b91af;">NorthwindEntities</span> ctx = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">NorthwindEntities</span>()) { <span style="color: #2b91af;">ObjectQuery</span><<span style="color: #2b91af;">Customer</span>> query = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">ObjectQuery</span><<span style="color: #2b91af;">Customer</span>>(<span style="color: #a31515;">"Customers"</span>, ctx); <span style="color: #0000ff;">foreach</span> (<span style="color: #2b91af;">Customer</span> c <span style="color: #0000ff;">in</span> query) { <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"ID [{0}], ContactTitle [{1}]"</span>, c.CustomerID, c.ContactTitle); } } |
3. ADO.NET Entity Framework Tool自动生成Entities和各个对象的代码,帮助开发人员减少了很多体力活。这样,我们可以简单写成:
1 2 3 4 5 6 7 8 9 |
<span style="color: #0000ff;">using</span> (<span style="color: #2b91af;">NorthwindEntities</span> ctx = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">NorthwindEntities</span>()) { <span style="color: #0000ff;">foreach</span> (<span style="color: #2b91af;">Customer</span> c <span style="color: #0000ff;">in</span> ctx.Customers) { <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"ID [{0}], ContactTitle [{1}]"</span>, c.CustomerID, c.ContactTitle); } } |
其实这里,也是使用ObjectQuery来进行查询。当然,可以给查询加上更多的条件,在上一篇文章中也有说明这里就不写了。 值得关注的是:自动生成的实体类中有这样一个方法,比如Customer:
1 2 3 4 5 6 7 |
<span style="color: #0000ff;">public</span><span style="color: #0000ff;">static</span><span style="color: #2b91af;">Customer</span> CreateCustomer(<span style="color: #0000ff;">string</span> customerID, <span style="color: #0000ff;">string</span> companyName) { <span style="color: #2b91af;">Customer</span> customer = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">Customer</span>(); customer.CustomerID = customerID; customer.CompanyName = companyName; <span style="color: #0000ff;">return</span> customer; } |
并不像以前一样,提供带参数的构造函数,而是提供CreateCustomer的静态方法来构造Customer实例。这似乎和前一段时候贫血充血的问题有关了,实体对象该不该有行为,是贫血还是充血?虽然只是一个方法,不过相信这也表明了微软的态度吧。 转自:http://www.cnblogs.com/blusehuang/archive/2007/10/14/923549.html
View DetailsADO.NET Entity Framework 学习(1)
前一段时间园子里有很多文章介绍分析了Linq To SQL,它可以说是一个简单实现的ORM,是微软针对数据和对象的阻抗不平衡的问题。C# 3.0推出一些新的特性,比如Extension Method, Lambda Expression, Anonymous Type,其实这些新特性都是用来为Linq服务。Linq To SQL将程序员从以往写大量的sql查询语句、取值、赋值中解放出来,在intellisense和编译上做了很多工作,使得这些查询能够在编译期进行检查。同时微软推出ADO.NET Entity Framework,即下一代的ADO.NET。它是比Linq To SQL更加强大的ORM,让开发人员只需要着眼于领域对象模型的开发,而不需要考虑它们是如何与关系数据库交互。 本文由一个简单的例子进行介绍Entity Framework是如何使用的。在此之前,必须下载ADO.NET Entity Framework runtime 和tools,官方也提供了很多示例下载。下面正式开始ADO.NET Entity Framework之旅(开发工具VS 2008 beta,以Northiwind数据库为例)。 首先建立一个Console project(要选择.NET Framework 3.5),然后点击Add New Item,看见ADO.NET Entity Data Model选项: 然后会出现Wizard,选择数据库,选择表、视图、存储过程等,按照向导一步步来就可以了,在这里只选择Customers和Orders表。在Solution Explore视图里面点击Northwind.edmx,可以看到Entity的信息(看上去很像Linq To SQL的dbml设计视图),然后将它们改名为Customer和Order。 现在我们就可以进行查询了,先引用命名空间:
1 2 |
<span style="color: #0000ff;">using</span> System.Data.Objects; <span style="color: #0000ff;">using</span> NorthwindModel; |
1 |
首先我们查询所有的Customer,代码和Linq To SQL中的十分相似。 |
1 2 3 4 5 6 7 |
<span style="color: #0000ff;">using</span> (<span style="color: #2b91af;">NorthwindEntities</span> ctx = <span style="color: #0000ff;">new</span><span style="color: #2b91af;">NorthwindEntities</span>()) { <span style="color: #0000ff;">foreach</span> (<span style="color: #0000ff;">var</span> customer <span style="color: #0000ff;">in</span> ctx.Customers) { <span style="color: #2b91af;">Console</span>.WriteLine(customer.CustomerID); } } |
接着来查询某个Customer,
1 |
<span style="color: #2b91af;">Customer</span> alfki = ctx.Customers.Where(<span style="color: #a31515;">"it.CustomerID = 'ALFKI'"</span>).First(); |
"it.CustomerID = 'ALFKI’"表示查询条件语句,该语句看着又像C#代码又像SQL,被成为Entity SQL Language,具体语法在帮助文档上有很详细的Reference。 这里也可以使用Linq进行查询(Linq To Entities),需要引用System.Linq命名空间,似乎Entity Framework不支持Single方法,会抛出异常。
1 |
<span style="color: #2b91af;">Customer</span> alfki = ctx.Customers.First<<span style="color: #2b91af;">Customer</span>>(it => it.CustomerID == <span style="color: #a31515;">"ALFKI"</span>); |
1 |
或者 |
1 2 |
<span style="color: #2b91af;">Customer</span> alfki = (<span style="color: #0000ff;">from</span> c <span style="color: #0000ff;">in</span> ctx.Customers <span style="color: #0000ff;">where</span> c.CustomerID == <span style="color: #a31515;">"ALFKIA"</span><span style="color: #0000ff;">select</span> c).First(); |
1 |
在Entity Framework中进行一对多的查询很简单,但是值得注意的是Entity Framework默认是Lazy Load,即关联数据在需要的时候才加载。 |
1 |
在本例子中,如果直接查询该Customer关联的orders,查询不到结果。 |
1 2 3 4 |
<span style="color: #0000ff;">foreach</span> (<span style="color: #0000ff;">var</span> order <span style="color: #0000ff;">in</span> alfki.Orders) { <span style="color: #2b91af;">Console</span>.WriteLine(order.OrderID); } |
需要在使用orders之前调用 alfki.Orders.Load(), 再次运行便可以得到正确的结果。
1 |
[未完待续] |
转自:http://www.cnblogs.com/blusehuang/archive/2007/10/10/920020.html
View DetailsX-UA-Compatible
1.<meta http-equiv="X-UA-Compatible" content="IE=5" />像是使用了 Windows Internet Explorer 7 的 Quirks 模式,这与 Windows Internet Explorer 5 显示内容的方式很相似。 2.<meta http-equiv="X-UA-Compatible" content="IE=7" />无论页面是否包含 <!DOCTYPE> 指令,都像是使用了 Windows Internet Explorer 7 的标准模式。 3.<meta http-equiv="X-UA-Compatible" content="IE=8" /> 4.<meta http-equiv="X-UA-Compatible" content="edge" />Edge 模式通知 Windows Internet Explorer 以最高级别的可用模式显示内容,这实际上破坏了“锁定”模式。 5.<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />EmulateIE7 模式通知 Windows Internet Explorer 使用 <!DOCTYPE> 指令确定如何呈现内容。标准模式指令以Windows Internet Explorer 7 标准模式显示,而 Quirks 模式指令以 IE5 模式显示。与 IE7 模式不同,EmulateIE7 模式遵循 <!DOCTYPE> 指令。对于多数网站来说,它是首选的兼容性模式。
View Details使用 HttpWebRequest 向网站提交数据
HttpWebRequest 是 .net 基类库中的一个类,在命名空间 System.Net 下面,用来使用户通过 HTTP 协议和服务器交互。 HttpWebRequest 对 HTTP 协议进行了完整的封装,对 HTTP 协议中的 Header, Content, Cookie 都做了属性和方法的支持,很容易就能编写出一个模拟浏览器自动登录的程序。 程序使用 HTTP 协议和服务器交互主要是进行数据的提交,通常数据的提交是通过 GET 和 POST 两种方式来完成,下面对这两种方式进行一下说明: 1. GET 方式。 GET 方式通过在网络地址附加参数来完成数据的提交,比如在地址 http://www.google.com/webhp?hl=zh-CN 中,前面部分 http://www.google.com/webhp 表示数据提交的网址,后面部分 hl=zh-CN 表示附加的参数,其中 hl 表示一个键(key), zh-CN 表示这个键对应的值(value)。程序代码如下: HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.google.com/webhp?hl=zh-CN" );req.Method = "GET";using (WebResponse wr = req.GetResponse()){ //在这里对接收到的页面内容进行处理} 2. POST 方式。 POST 方式通过在页面内容中填写参数的方法来完成数据的提交,参数的格式和 GET 方式一样,是类似于 hl=zh-CN&newwindow=1 这样的结构。程序代码如下: string param = "hl=zh-CN&newwindow=1";byte[] bs = Encoding.ASCII.GetBytes(param); HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.google.com/intl/zh-CN/" );req.Method = "POST";req.ContentType = "application/x-www-form-urlencoded";req.ContentLength = bs.Length; using (Stream reqStream = req.GetRequestStream()){ reqStream.Write(bs, 0, bs.Length);}using (WebResponse wr = req.GetResponse()){ //在这里对接收到的页面内容进行处理} 在上面的代码中,我们访问了 www.google.com 的网址,分别以 GET 和 POST 方式提交了数据,并接收了返回的页面内容。然而,如果提交的参数中含有中文,那么这样的处理是不够的,需要对其进行编码,让对方网站能够识别。 3. 使用 GET 方式提交中文数据。 GET 方式通过在网络地址中附加参数来完成数据提交,对于中文的编码,常用的有 gb2312 和 utf8 两种,用 gb2312 方式编码访问的程序代码如下: Encoding myEncoding = Encoding.GetEncoding("gb2312");string address = "http://www.baidu.com/s?" + HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding);HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);req.Method = "GET";using (WebResponse wr = req.GetResponse()){ //在这里对接收到的页面内容进行处理} 在上面的程序代码中,我们以 GET 方式访问了网址 http://www.baidu.com/s ,传递了参数“参数一=值一”,由于无法告知对方提交数据的编码类型,所以编码方式要以对方的网站为标准。常见的网站中, www.baidu.com (百度)的编码方式是 gb2312, www.google.com (谷歌)的编码方式是 utf8。 4. 使用 POST 方式提交中文数据。 POST 方式通过在页面内容中填写参数的方法来完成数据的提交,由于提交的参数中可以说明使用的编码方式,所以理论上能获得更大的兼容性。用 gb2312 方式编码访问的程序代码如下: Encoding myEncoding = Encoding.GetEncoding("gb2312");string param = HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding) + "&" + HttpUtility.UrlEncode("参数二", myEncoding) + "=" + HttpUtility.UrlEncode("值二", myEncoding); byte[] postBytes = Encoding.ASCII.GetBytes(param); HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.baidu.com/s" );req.Method = "POST";req.ContentType = "application/x-www-form-urlencoded;charset=gb2312";req.ContentLength = postBytes.Length; using (Stream reqStream = req.GetRequestStream()){ reqStream.Write(bs, 0, bs.Length);}using (WebResponse wr = req.GetResponse()){ //在这里对接收到的页面内容进行处理} 从上面的代码可以看出, POST 中文数据的时候,先使用 UrlEncode 方法将中文字符转换为编码后的 ASCII 码,然后提交到服务器,提交的时候可以说明编码的方式,用来使对方服务器能够正确的解析。 以上列出了客户端程序使用 HTTP 协议与服务器交互的情况,常用的是 GET 和 POST 方式。现在流行的 WebService 也是通过 HTTP 协议来交互的,使用的是 POST 方法。与以上稍有所不同的是, WebService 提交的数据内容和接收到的数据内容都是使用了 XML 方式编码。所以, HttpWebRequest 也可以使用在调用 WebService 的情况下。 转自:http://www.cnblogs.com/webman/archive/2006/11/17/564106.html
View Details感谢这一切
今天去中欧上班,真是扯淡。 老板不在,没有位置,没有电脑,真是悲催。 更郁闷的是有个SB却让我做主管,本来谈好的是总监。 人力说不用管他,面谈我的邱SIR直说抱歉;这的技术也像中业一样混乱。TMD的模式也一样,因为有个SB。 我是文明人,不想骂人。但现在有些人不厚道的人就会出现在那些不厚道的公司。今天的事对我来说是好事,总比上了一两月班再有状况要好。 中欧也够TMD的不厚道的,和中世商务一样,25号发工资,MD10号发工资已经是压工资10天了。最近几年工作过的公司还就北京西蔓和上海拜般还说的过去。可惜都不是内地的公司。由此可见内地和发达地区商业环境的差距。 不过,要感谢这一切的工作经历,让我更加坚信自己的理念,要想舒服的工作环境,要想工作在一个有理想、有作为的公司就只有自己做,需要自己去浇灌爱心。
View Details为什么Linux不需要磁盘碎片整理
如果你是个Linux用户,你可能听说过不需要去对你的linux文件系统进行磁盘碎片整理。也许你注意到了,在Liunx安装发布包里没有磁盘碎片整理的工具。为什么会这样? 为了理解为什么Linux文件系统不需要磁盘碎片整——而Windows却需要——你需要理解磁盘碎片产生的原理,以及Linux和Windows文件系统它们之间工作原理的不同之处。 什么是磁盘碎片 很多Windows用户,甚至是没有经验的用户,都深信经常对文件系统进行碎片整理会提高计算机的速度。但并不是很多人知道这其中的原委。 简单的说,磁盘驱动器上有很多扇区,每个扇区都能存放一小段数据。文件,特别是大文件的存储需要占用很多不同的扇区。假设现在你有很多个文件存在的文件系统里,每个文件都会被存储在一系列连续的扇区里。后来你更新了其中的一个文件,它的体积变大了。文件系统会尝试把文件新增的部分存放到紧邻原始文件的扇区里。可不幸的是,它周边已经没连续的足够扇区空间了,文件需要被分割成数段——这些都在自动进行的。当从磁盘上读取这个文件时,磁盘磁头需要跨越数个不同的物理位置来读取各个扇区——这样会使速度降低。 磁盘碎片整理就是小心的移动这些小文件块来减少碎片,让每个文件都能连续的分布在磁盘上。 当然,如果是固态硬盘,那情况又不同了,固态硬盘没有机械移动,不应该进行碎片整理——对一个U盘进行碎片整理通常会降低它的寿命。在最新版的Windows系统里,你实际上不需要关心系统上的碎片——Windows会自动替你整理。 Windows文件系统的工作原理 微软老的FAT文件系统——最后一次使用是在Windows 98 和 Window ME上,可如今的U盘上还在使用它——并不会智能的管理文件。当你把一个文件存入FAT文件系统里时,系统会尽量的把它存到靠近磁盘开始的地方。当你存入第二个文件时,它会紧接着第一个文件——一个接着一个。当原始文件体积变大后,它们一定会产生碎片。根本没有留给它们增长的空间。 微软新的NTFS文件系统——使用在装有Windows XP和2000的PC机上——稍微智能了一点。它会在磁盘上在文件周围分配一些“缓冲”的空闲空间,尽管如此,任何Windows用户都会告诉你,经过一段时间的使用后,NTFS文件系统还是会形成碎片。 由于这些文件系统的工作原理,它们注定需要进行碎片整理来保持高性能。微软在它最新的视窗系统里通过在后台运行一个磁盘碎片整理进程来解决这个问题。 Linux文件系统的工作原理 Linux的ext2, ext3, 和 ext4 文件系统 ——Ubuntu和大多数最新的Linux发布版中使用的是ext4——采用了一种更聪明的方法来存放文件。与把多个文件并排放在磁盘上不同,Linux文件系统把所有文件都分散到了整个磁盘上,每两个文件之间都留有相当巨大的空闲空间。当文件被修改、体积增加时,它们通常有足够的空间来扩展。一旦有碎片产生时,文件系统会尝试移动整个文件来消除碎片,所以你不需要一个碎片整理工具。 因为这种工作方式,当磁盘快要装满时,你开始会发现有碎片开始产生。如果已用空间超过95%(甚至80%),你会发现碎片开始变多。但不管怎样,这个文件系统的设计会使正常情况下不产生碎片。 如果你在Linux系统上遇到了磁盘碎片问题,你很可能需要一个更大的硬盘了。如果你真想整理一个文件系统,这最简单的方式也许是最可靠的方式:把文件从这个分区里考出,删除这些文件,然后考回这些文件。当你把文件考回硬盘时,文件系统会智能为文件分配存储空间。 你可以使用 fsck 命令来查看Linux文件系统上的磁盘碎片情况——在输出结果里寻找“non-contiguous inodes”信息。 [英文原文:Why Linux Doesn’t Need Defragmenting ]
View DetailsMicrosoft Ajax调用Webservice
1.Default.aspx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ScriptWebSerivce" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title></title> <script type="text/javascript"> function ShowResult(res) { alert(res);} </script> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="MyWebService.asmx" /> </Services> </asp:ScriptManager> <script type="text/javascript"> Ajax.MyWebService.GetTotal(5, 4, ShowResult, null, "abc"); </script> </div> </form> </body> </html> |
2.MyWebService.asmx.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Web.Script.Services; namespace Ajax { /// <summary> /// MyWebService 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] //[System.ComponentModel.ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 [ScriptService] public class MyWebService : System.Web.Services.WebService { public MyWebService() { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public int GetTotal(int x, int y) { return x + y; } } } |
注意:此方法只适合在同一个域下调用。
View Details作为开发者,你不应该害怕的 8 件事
1. 改变 在软件开发中,没有什么事情会一直停滞不前。现在你正在开发的东西,只是软件的其中一个版本,未来随时可能发生变化。 变化是在软件开发中最常见的事情,你最好接受这一事实。一种好的做法是,使你的代码更加模块化,这样在未来需求改变时,可以容易地进行更改。 遵循DRY(Don't Repeat Yourself)和YAGNI(You Aren't Gonna Need It)原则。经常看看你的代码,相信自己可以做得更好。立即采取行动,并进行重构,你等的时间越长,代码维护起来就越艰难。有可能会混乱到你无法处理。 好代码是很容易改变的代码。代码会不断改变,直到它不再容易改变为止。那时所有的代码已经变成了糟糕的代码。—— 匿名 2. 移除死代码和注释掉的代码 在开发中,往往会遇到一些无用的或注释掉的代码,你可能不愿意删除,因为你不知道它们以后会不会排上用场。 立刻删除了吧!因为有版本管理工具来负责记住这些代码。现实中太多的项目充斥着大量注释掉的代码,如果不需要,就删除吧,不要害怕。 完美,不是在没有东西需要补充的时候,而是在没有东西需要去掉的时候。——《小王子》 3. 犯错误 没有人是完美的,每个人都会犯错误。犯错是一个学习的过程。如果你不承认任何错误,你将不会有任何改善。 所以,每当你犯了一个错误的时候,你要从中学到一些新的东西,来提高你的知识。此外,不要隐藏自己的错误,或为它们感到羞愧,诚实、坦率地说出你的错误,为自己或他人作前车之鉴。批评与自我批评是推动一个成功团队向前的重要工具。 从未犯过错误的人,是没有机会尝试新东西的。—— 阿尔伯特•爱因斯坦 4. 向其他人展示你的代码 你是不是害怕其他人审查你的代码?为什么呢?你没有尽全力写好吗?你害怕犯任何错误吗? 你不应该这样,代码审查中发现的每一处错误都可以为你积累一些经验,在以后的编码中,你将不会再犯同样的错误。因此,你应该为你写的代码感到骄傲,不要害怕别人看到。 5. 失败 这是最重要的一个。如果你害怕失败,那么你将永远无法解决手头的问题。永远不要放弃希望,把它当作是一个挑战。尝试从另一个角度看东西。成功地解决难题之后,会让你更加强大。 我并没有失败,我刚刚发现了1万种无法正常工作的方式。——托马斯•爱迪生 6. 你自己代码的稳定性 你向你的老板或客户展示你的项目时,你开始担心“能正常运行吗?希望我在开发过程中没有遗漏什么。” 这是一个不好的征兆,你不应该担心。你应该尽早测试你的项目。当然,你无法100%肯定你的作品是完美的,但通过编写自动化测试,可以大大提高你对你的代码的信任度。 7. 新的、复杂的技术 有些开发人员很懒惰,经常沉浸在他们的“Good Old”技术中。要知道,IT正在以令人难以置信的速度发展,每一天都会有新的、更好的技术出现。 因此,开发人员要以开放的态度,多学习一些东西,阅读一些博客,使你不至于与新技术脱节。如果技术/框架满足你的需求,尝试一下也无妨。 8. 项目时间压力 别让时间压力毁了项目的质量。保证你的代码干净、稳定,这是你的工作。高质量也意味着需要深思熟虑的决策和开发时间,有时你需要争取一下。你的客 户期待你用100%(甚至120%)的努力来完成一个可维护的、最先进的产品,如果最终你交付一个次品,那么你后面的时间将被各种需求变更、维护工作占 用,并且老板和客户对你的信任度也会降低。 在开发中,你节省的时间往往会为你带来更多的技术债务。因此,当涉及到项目质量时,拿出你的勇气,诚实地与你的老板谈谈。 编程就像性一样:一次犯错,终生维护。——Michael Sinz 英文原文:8 Things you should not be afraid of as a Developer/iteye翻译 转自:http://www.oschina.net/news/38760/8-things-you-should-not-be-afraid-of-as-developer
View Details