Linux.NET学习手记(4)
前一回合中我们已经对Jexus作了一个详细深入的学习,如果各位读者有仔细的阅读文章并且有进行实际的操作,相信玩转Jexus这款高性能服务器软件绝对并非难事,至此为止,Jexus的学习到此结束,我们也正式的进入到下一个学习的正题当中。
前面几个回合以来,我们一直都在Linux.NET的边缘中徘徊,始终都没有部署过任何的一个.NET的网站应用程序,为的就是让读者们先弄清楚Linux.NET到底是怎么一回事,同时也让各位读者对Linux.NET或多或少的有一些了解,所谓“万丈高楼平地起”,如果在没有任何基础的情况下直接在Linux中部署.NET网站应用程序,这将会遇到不少的困扰。这里我建议各位打算学习Linux.NET的读者们,应当先对Asp.NET和Linux的操作有一定的了解,毕竟本系列的文章并不是单纯的讲解Asp.NET,也不是Linux的使用教程,而是建立在它们共同之上的一种领域。此外各位读者也应当懂得怎么使用Jexus(或其他能够提供.NET运作的Linux服务器软件),这样子我们才能够以一种比较轻松的方式来共同的对Linux.NET进行学习。
在今后我们将会把一些已经在Windows中写好的ASP.NET网站进行尝试性的向Linux迁移部署,看它们能否成功的从Windows向Linux迁移,迁移后是否满足我们的需求,当然,由于Windows和Linux终归是两种不同的系统,迁移的过程中会遇到各种各样的阻力,这需要我们的读者见招拆招,在不断的摸索中令我们的Linux.NET大军能够不断挺进。同时各位读者如有任何关于Linux.NET的心得体会,在Linux中部署.NET的技巧,欢迎各位读者进行分享;本文中如有不科学的地方,也欢迎各位读者留言指正。
正式进入到本回合的正题,案例代码可以点击这里下载:
在本回合中,我们将讨论学习:
(1)、在Mono中部署一个简单的在线加法器
(2)、结合数据库,在Mono中部署一个简单的增删查改站点
(3)、在Mono中使用轻量的ORM——PetaPoco
1、牛刀小试
在进行各种大中小规模的.NET部署之前,我们先来进行一次的超小规模的.NET部署测试,让各位读者先体验一下在Mono中运行.NET网站是怎么一回事。当然,我们现在部署东西会比知名的“Hello World”高级一点,我们将要部署的是一个简单的CodeBehind加法计算器。
针对本回合的所有实验,我们新开一个Jexus的虚拟主机:
然后在Windows中的Visual Studio写一个简单的网站。
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> 2 3 <!DOCTYPE html> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 8 <title></title> 9 </head> 10 <body> 11 <form id="form1" runat="server"> 12 <div style="background-color:pink;height:40px;width:600px;padding:10px;"> 13 <asp:TextBox ID="Addend1" runat="server"></asp:TextBox> + 14 <asp:TextBox ID="Addend2" runat="server"></asp:TextBox> 15 <asp:Button ID="Sum" runat="server" Text="=" OnClick="Add" /> 16 <asp:TextBox ID="Result" runat="server" ReadOnly="true"></asp:TextBox> 17 </div> 18 </form> 19 </body> 20 </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Add(object sender, EventArgs e) { int a = Convert.ToInt32(Addend1.Text); int b = Convert.ToInt32(Addend2.Text); Result.Text = (a + b).ToString(); } }
最后把网站发布到Linux中指定的根目录(/var/www/Linux.NET4/)中,并重启Jexus。
成功的访问并计算~~~!!!
这里有几个需要提醒的地方:
(1)、部署完.NET之后,Jexus需要重启才能生效(至少要对部署的网站进行重启)
(2)、习惯使用Apache的,特别是习惯使用或者最近一直都在使用动态语言的读者,要留意编译型和解析型语言的区别。站点内容必须放置在Jexus配置的指定根目录中,换句话就是:bin、app_code等文件夹所在的目录级别必须是网站的根目录。在下就曾经犯二的把.NET的一个网站放到了非Jexus网站根目录的一个文件目录中,结果编译发布之后老报找不到XXX的错误,结果郁闷了老半天才恍然大悟。
(3)、各位读者可以自由选择“直接采用源码上传到Jexus中发布”或者“本地编译发布网站,再上传编译后的网站到Jexus中”。如果目标Linux是处于局域网中,各位读者还可以直接采用samba等软件把网站根目录文件夹共享出来,这可以更方便的上传发布网站。
2、PostgreSQL与Mono的结合
一个网站(除静态站点)的正常运行必然是需要和数据进行打交道的,我举个例子,比如我们现在去淘宝买一本书,当我们登陆时,淘宝需要对我们的登陆信息进行验证,验证我们的用户名密码是否正确;当我们需要搜索需要的商品时,淘宝需要对我们需要的产品进行筛选,并把筛选后的结果推送到我们的浏览器供我们查阅;浏览了好一阵子之后,我们发现自己想要的心水商品时,然后点击下单并填写配送信息,淘宝还需要登记下我们的配送地址、联系电话等相关信息……可以看出,从我们输入淘宝这一网址并回车这一刹那开始,我们就不断的和淘宝进行各种的数据交互,我们的每一个操作,无论是登陆、下单还是搜索、翻阅,全部都涉及到大量的数据交互。各位读者是否有想过,我们在网站中干了那么多的事情,填写了这么多的表单信息,淘宝又是怎样把我们的信息记录下来,又应该记录到哪里?Of Course,各位读者答得非常好,它就是通过淘宝网的数据库进行记录下来的。
而事实上,我们当今在网上遇到的除静态网站之外的大部分站点(包括任何的在线论坛、网上商城、XXX的发布系统……),它们都需要对用户的操作进行或简单或详细的记录,而这些信息记录必然是需要通过某种存储方式保存到服务器中,因此数据库都是是它们的共同的最佳选择,不同的只是它们可能并不是使用同一种的数据库而是其它各种类型的,Ms SQLServer、MySQL、DB2或者是一些非关系型的NOSQL数据库。
在写本篇文章之前,我就一直在考虑,《Linux.NET学习手记》应该采用那一款的数据库,到底是使用我在Linux中一直使用的MySQL还是我所认知的那些拥有丰富Linux.NET开发经验的前辈们普遍使用的PostgreSQL。网上关于MySQL和PostgreSQL对比的文章也有不少,讲得比较精辟的有:《PostgreSQL和MySQL的对比》和《MySQL VS PostgreSQL》。最后经过再三思考之后,我决定选择使用PostgreSQL,选择该数据仅仅是基于一些个人(私人的)原因。各位读者未必也必须要使用PostgreSQL,可以按照自己的喜好和业务的需求来选择自己心水的数据库软件,顺带的呼吁一下:各位读者请不要作任何的数据库之争,因为数据库之争就跟语言之争一样毫无意义,从来就没有哪款数据库好哪款数据库不好的这么一个说法,只有在哪个领域或者哪个项目之中哪款更合适。
好的,说得有点多了。关于如何在Linux下部署PostgreSQL,这里我推荐两篇园子中的文章,它们分别是介绍使用yum和源码包的方式部署PostgreSQL:《CentOS 6.3 Minimal yum 安装 PostgreSQL 9.2.3》和《CentOS 6.3 Minimal 源码安装 PostgreSQL 9.2.3》,各位读者可以自行的选择喜欢的方式部署PostgreSQL。另外,由于本文的重点并不是介绍PostgreSQL如何使用,因此各位读者如果不懂如何使用PostgreSQL的,可以自行的从网上搜索相关的资料(我个人手头上也有少量的关于PostgreSQL的资料,有需要的读者可以发站内信或在微博上私信或@我)。
首先,我们先在建立我们的数据库和表,这里我不介绍数据库和表如何建立,只是给出表的结构,其结构如下:
然后在我们的解决方案中新建一个新的网站“Example2” ,添加上我们需要的PostgreSQL的连接器,各位读者可以点击这里,链接到官网上上下载或通过其他办法来获取该工具包。
在这里我们通过另外的一种方式,采用Visual Studio所提供的便捷功能”NuGet“来快速的获取并自动部署到我们的网站项目中。
使用方法非常简单,只需点击:”工具-->库程序包管理器-->库程序包控制台“调出控制台,然后在控制台中输入"Install-Package Npgsql"并回车执行即可。
这样,我们就可以通过NuGet非常简单并且快速的把PostgreSQL的连接器”Npgsql“部署到我们的项目当中。
然后我们在配置文件”Web.Config“中添加上PostgreSQL的连接字串:
<?xml version="1.0"?> <configuration> <connectionStrings> <add name="postgres" connectionString="Host=127.0.0.1;User ID=postgres;Password=postgres;database=test"/> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0"/> </system.web> </configuration>
接着我们在采用最简单的办法写出增、删、查、改的代码(这里不作粘贴展示,各位读者请移步到项目代码中查看)。接着我们再发布并上传网站,通过操作得出我们需要的结果:
这里有几点注意需要提醒各位读者:
(1)、使用NuGet部署“Npgsql”时,要注意控制台中部署项目是否正确选中我们需要部署的项目。
(2)、如果各位读者的Mono与PostgreSQL不是安装到同一台的Linux中,需要注意数据库的授权问题,更详细的各位读者可以阅读PostgreSQL的手册,上面有详细的概述。
(3)、网站上传之后各位读者别忘了把Jexus重启。
3、Mono中使用PetaPoco
微软的ADO.NET技术给予了我们对数据库的操作极大的方便,无论我们面对的是何种的数据库,只要这款数据库的厂商有提供基于.NET的连接器,我们都可以采用ADO.NET的五大对象(Connection、Command、Reader、Adapter、DataSet)再配上通用的“T-SQL”语句来连接并操作这款数据库。我们几乎可以在不认识这款数据库的情况下完成对改数据库的操作,当然,我这里所说的操作指的是通用的“T-SQL”的操作,对于数据库的特色(特有的)高级功能或者另外一些不支持“T-SQL”的数据库,采用这种方法就未必适用了。
尽管ADO.NET已经是极大的方便了,但我们仍然免不了许多繁琐的工作,我们仍然需要一遍又一遍的对“T-SQL”语句进行拼接,一遍又一遍的调用我们写好的SQLTool(或SQLHelper),如果数据库中表比较少问题还尚算不大,但是如果数据库中的表很多,达到几十或上百个,这种“上螺丝”的操作不仅会花费我们大量的编码时间,还让我们的编码乐趣下降。还有更可悲的,那就是直接使用这些原生方法得到的结果返回集是一个弱类型的数据集,我们使用的时候还很可能的需要对返回的数据集进行逐一的数据类型转换,我们或许还要重新翻开数据库或者字段定义表来查阅该数据到底是一个什么类型。
面对这种情况,使用ORM(对象关系映射)可以很好的在一定程度上解决我们现有的问题,我们可以通过配置XML文档的方式(如果使用“Code-First”之类的技术甚至连配置XML还可以免除)把数据库中的表与我们项目中的实体类进行映射,我们就可以非常容易的得到一些强类型数据集,此外不少的ORM框架还会内置一些我们常用的CRUD的方法,一些甚至连常用数据库的连接器也内置,给予了我们极大的便利。
Entity Framework(以下简称ef),它是微软提倡使用的一款ORM框架,相信应该有不少读者知道并且懂得怎么使用,特别是做过.NET MVC开发的读者,ef更是MVC的标配,我自己也非常喜欢这款ORM框架,无论是它的姓名还是它的性能。但是本文中不会简介如何在Mono中使用ef来对PostgreSQL进行实体映射,原因非常简单,Mono中的ef框架比微软在Windows中正式发布的版本要高了整整一个版本。微软当前发布的ef正式版本为ef5,而Mono中存在的ef版本却是ef6,并且Mono还不支持低于ef6的ef框架。虽然各位读者也可以在NuGet控制台中通过“Install-Package EntityFramework -Prerelease”来获得处于未发行的ef6框架,但是正因为它还没有发行,如果各位读者强行的把此版本的ef框架部署到项目当中,PostgreSQL(包括MySQL)的数据库连接器都会因为版本问题而无法被ef识别,最终还是无法使用该ORM框架对数据库进行操作。
既然现有的ef无法对PostgreSQL提供支持,而我们又想使用ORM框架,那就得寻找ef的替代品,在寻寻觅觅的过程中,我从一位网友随口报的一款轻量级ORM框架中找到了答案。没错,这款框架就是小节标题上写的“PetaPoco”。关于PetaPoco的介绍和使用方法,各位读者可以参考:PetaPoco官网、.NET对象关系映射器PetaPoco、OoC's Blog,它们都有比较清晰而详细的介绍PetaPoco如何使用,各位读者可以点击链接并学习。
我们为本小节实验新建一个新的网站“Example3”。
然后再添加上我们的PetaPoco库,各位的读者可以从PetaPoco的官网上获取,在这里,我们仍然使用 Visual Studio 提供的快捷功能,使用NuGet控制台来在线的获取并把PetaPoco部署到我们的网站项目当中。它的命令为:”Install-Package PetaPoco“。
然后在我们的网站配置文件”Web.Config“中添加好我们的连接字串
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="postgres" connectionString="Host=127.0.0.1;User ID=postgres;Password=postgres;database=test"/> </connectionStrings> <system.web> <compilation debug="false" targetFramework="4.0" /> </system.web> </configuration>
在Model中添加上我们的”Person“实体类:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using PetaPoco; /// <summary> /// Person 实体类 /// </summary> [PetaPoco.TableName("person")] [PetaPoco.PrimaryKey("id")] public class Person { [PetaPoco.Column("id")] public int ID { get; set; } [PetaPoco.Column("name")] public string Name { get; set; } [PetaPoco.Column("age")] public int Age { get; set; } [PetaPoco.Column("sex")] public string Sex { get; set; } }
跟第二节一样,添加一个Aspx页面,添加”增“、”删“、”查“、”改“四个按钮并完善里面的代码(这里也不贴代码了,各位读者需要阅读的请移步到项目当中),之后发布上传我们的网站到Linux中,重启Jexus,得到我们想要的效果:
在这里,我需要提醒一下各位读者:因为PostgreSQL中默认是小写的,即在Linux的PostgreSQL控制台中,如果读者们对字段没有使用双引号修饰,无论读者们使用大写还是小写,PostgreSQL都会自动的把字母转换为小写。而在这里,我们的实体类Person中属性的命名规则是采用帕斯卡命名法(大写开头),如果读者们没有对实体类中的属性加标签(手动的指明该实体属性对应数据库中的字段名)或者在调用PetaPoco的方法时手动的指明数据库中的对应字段名,网站运行时就有可能发生异常。因此,为了避免不必要的麻烦,并且增加代码的可读性,我建议各位读者在写实体类的时候顺带把该实体和里面的属性进行手动的数据映射。
就这样,我们对Linux搭建和部署.NET网站做了一个抛砖引玉,同时也证明了Linux中跑.NET的可能性与可行性,好的,我们这回合暂时就到这里结束。
下一节,我们尝试在Mono中部署一款优秀的开源框架,也就是在已经在Java中大行其道的Spring,我们部署的是Spring.NET,嗯,我们下回见。