从SqlHelper到EF Core:一个老菜鸟的回忆录
开头
收拾旧硬盘,翻到一个十几年前的文件夹。里面躺着一个Winform项目,点开一看,熟悉的SqlHelper.cs、StringHelper.cs、DateHelper.cs整整齐齐排在那里。还有一个叫“常用代码片段”的文件夹,里面塞满了从网上复制下来的各种工具类。
愣了愣神。
那时候这些东西就是我的全部家当,每次开新项目第一件事就是把它们拷进去。现在想想,已经好多年没这么干过了。
突然就想把这些年的变化记下来。不是总结,不是分析,就是随便聊聊。
一、数据库访问这件事
最开始写.NET的时候,没有Entity Framework,甚至没有实体类这个概念。
查数据用的是DataSet、DataTable:
csharp
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
}
取字段值的时候,dt.Rows[i]["UserName"],字段名是字符串。拼错一个字,编译期不报,运行时报,找半天。
后来开始自己建实体类。一个表对应一个类,字段一个一个手动映射:
csharp
user.Id = Convert.ToInt32(dr["Id"]); user.Name = dr["Name"].ToString();
表多了以后,这种赋值代码写到手软。
每个项目都有一个SqlHelper,自己封装连接、参数、事务。写得多了,这个Helper越来越完善,成了自己的“传家宝”,每次开新项目先把它拷进去。
再后来,Entity Framework出来了。刚开始不太信任,总担心它生成的SQL靠不靠谱。用edmx拖表生成模型,感觉挺高级,但复杂查询还是习惯手写SQL。新旧混着用了好长一段时间。
现在写EF Core,一行Linq就查完了,不用管连接开闭,不用手动映射。偶尔抓日志看看生成的SQL,心里想:要是当年有这个,得省多少事。
二、异步这件事
刚入行那会儿,程序大部分是同步的。点个按钮,界面卡住,等操作完成,用户就干等着。
后来知道用BackgroundWorker开个后台线程。但想更新UI,得用Invoke:
csharp
this.Invoke((Action)(() => { label1.Text = "完成"; }));
一不小心就跨线程访问异常,调试半天。
再后来有了BeginXXX/EndXXX那套异步模式。IAsyncResult、AsyncCallback,一个简单的操作,逻辑被拆成回调套回调。写的时候还行,过两个月自己回来看,得捋半天。
Task出来以后好了一些,但ContinueWith写多了也还是回调的思路,嵌套深了不好读。
第一次用async/await的时候,感觉就是:原来异步可以这么写。同步的写法,异步的执行,try-catch正常用,代码读起来从头到尾一条线。
现在写API,Controller里清一色async Task,await一路下去。偶尔忘了加await,编译器给个警告,想一下要不要改。写异步变成了自然而然的事,不用刻意去想。
三、从页面到接口
最早做Web开发,写的是aspx页面。
拖服务器控件:Button、Label、GridView。页面背后有个Page_Load,里面写if (!IsPostBack)判断是第一次加载还是回发。
那时候有个东西叫ViewState,藏在页面源码里,一个巨大的隐藏字段。一个复杂的GridView,ViewState能到几十KB。页面打开慢,但大家都这样。
Postback也是日常。点个按钮,整个页面刷一下,屏幕闪一下。做省市级联下拉框,选省份,Postback,页面一闪,市区出来了。现在想想体验挺差的,但当时习惯了。
后来MVC出来了,用Razor写视图,不拖控件了,直接写HTML,感觉自由了不少。但主要还是服务端渲染,返回View()。
再到现在,基本都在写API。标个[ApiController],返回JSON。前端用什么框架是前端的事,后端专注业务逻辑和数据。
偶尔打开一个老项目,看到那些aspx页面和ViewState,有点恍惚:原来以前是这么写的。
四、前端那些事
虽然主业是后端,但那会儿没分那么清,前端也得自己写。
手写JavaScript
最原始的时候,纯手写JavaScript。document.getElementById,又长又烦。不同浏览器还不一样,写个兼容代码要查半天。
表单验证自己写正则,alert弹窗提示,用户觉得丑,自己也觉得丑。
写Ajax更是麻烦。new一个XMLHttpRequest,监听onreadystatechange,判断readyState和status,拿到返回数据自己解析。一个简单的请求,代码一大坨。
CSS和浏览器兼容
写CSS也是一言难尽。那时候浏览器市场还是IE6的天下,后来有了IE7、IE8,还有Firefox、Chrome慢慢起来。同一个样式,不同浏览器显示出来不一样。
为了一个div居中,各种margin: 0 auto不行就text-align,再不行就上position。为了兼容IE6,还得搞各种hack。
最头疼的是那个“盒模型”。IE的盒模型和W3C标准不一样,宽度计算差一个padding和border。写个宽度得算半天,这边对了那边又歪了。
IE6还有个著名的“双边距bug”,浮动元素的外边距会翻倍。怎么解决?加一句display: inline。为什么加这个就好了?当时也没深究,反正加了就行。
为了照顾不同浏览器,CSS里经常出现下划线hack、星号hack:
css
.box {
width: 200px; /* 标准浏览器 */
*width: 180px; /* IE7 */
_width: 160px; /* IE6 */
}
这种东西现在看起来像天书,但当时写起来轻车熟路。
最让人崩溃的是IE6不支持PNG透明。页面设计稿上漂亮的半透明阴影、圆角图标,到IE6上就是个灰白底。解决办法要么用gif凑合,要么加一段滤镜代码强行支持。每次遇到都头疼。
一个页面写完,得在IE6、IE7、IE8、Firefox里分别打开看一遍。哪个浏览器不对了,就针对它加hack。有时候改好了一个,另一个又坏了,调来调去一下午就过去了。
那时候有个词叫“优雅降级”,说白了就是:高级浏览器好看点,低级浏览器能用就行。但其实大部分时间,是老板和客户要求所有浏览器“看起来一样”。这句话听到就头大。
jQuery来了
后来遇到了jQuery。
第一次用$("#id")的时候,觉得太方便了。选择器好用,链式调用顺畅。它把浏览器差异封装好了,不用再操心兼容问题,这是最让人感动的地方。
还有它封装的Ajax:$.ajax、$.get、$.post,几行代码搞定一个异步请求,终于不用手写那一长串XMLHttpRequest了。
秘密武器:jQuery插件库
那时候有个网站叫jQuery插件库,是我的常驻网站。
项目要轮播图,上去搜slider。要日期选择器,搜datepicker。要弹窗、分页、图片灯箱、文件上传,全去上面找。
找到一个差不多的,下载下来,一个js文件、一个css文件丢到项目里。照着示例代码改参数,效果就出来了。同事看到问我这是你自己写的?我就笑笑说找的插件改的。
说是“找的”,但“改”这个字才是重点。下载的插件不太可能完全符合需求。你得打开它的源码,看懂逻辑,改样式,调参数,有时候还得动它的核心代码。
改着改着,这个插件就变成你自己的了。你对它的每一行都熟了,出问题知道去哪修。这个过程挺有意思的。
现在前端框架和组件库太多了,npm install一下,什么都有。浏览器兼容也好了很多,Chrome一家独大,IE退场了,flex和grid布局随便用,再也不用写那些奇怪的hack了。
方便是真方便。但偶尔还是会想起当年在插件库里淘东西、调样式、改源码的日子,还有那些被IE6支配的下午。
五、包管理这件事
没有NuGet的时候,引用第三方库是个体力活。
在网上找到别人写的工具类,下载.cs文件,拖到项目里。更好一点的,找到编译好的dll,右键添加引用。
最怕的是dll依赖另一个dll,那个又依赖第三个。少一个就报错,然后满世界去找。那时候大家管这个叫“DLL地狱”。
我自己攒了一个代码文件夹,里面有SqlHelper.cs、LogHelper.cs、ConfigHelper.cs。每个新项目,先把这个文件夹拷进去。那就是我的全部家当。
后来NuGet出现了。第一次在VS里右键看到“管理NuGet程序包”,搜索Json.Net点安装,几秒钟搞定。不用手动下载,不用管依赖,感觉太省心了。
现在用dotnet CLI,dotnet add package一行命令就行。NuGet上什么都有,序列化的、日志的、ORM的、各种SDK。生态比以前丰富了不知道多少。
偶尔会想起以前那个代码文件夹,不知道躺在了哪个旧硬盘里。
六、写在最后
好了,啰啰嗦嗦写了这么多。
其实写这些,不是想说以前多苦或者现在多好。只是那天看到旧硬盘里那些代码,心里涌上来一种说不清的感觉。那些SqlHelper、那些ViewState、那些IE6的hack、那些在插件库里淘来的js文件,它们都还在硬盘里躺着,但写这些代码的日子,确实过去了。
有时候跟年轻的同事聊天,他们不知道什么是ViewState,没经历过DLL地狱,也没被IE6折磨过。我觉得挺好的,每个时代有每个时代的工具和写法。
但如果他们也像我一样,十几年后翻到今天写的代码,会不会也有同样的感慨?
那就不知道了。
就这样吧,一篇碎碎念,留个纪念。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)