C#三层架构的Folder项目
来源:互联网 发布:csol淘宝租号 编辑:程序博客网 时间:2024/05/22 14:56
刚刚写完了用silverlight+wcf完成的Folder项目,其实刚开始的时候是先用c#用三层架构先做的,现在我就讲解一下我用三层架构做的Folder项目。
对于大部分.net程序员来讲,三层架构应该不陌生了,但是我之前并未在这里的博客记录过,所以我还是有必要再写一次,所谓三层架构分别是DAL(数据)层、BLL(逻辑)层和UI(界面)层,但是注意,三层架构虽然说是三层,但通常都会再加一层model层作为数据实体层,这样就更加能把三层分离开来了,具体关系如下图
UI层是不会直接对数据库进行操作的,而是通过逻辑层调用数据层,界面层再调用逻辑层来完成的,所以BLL层引用DAL层但不引用UI层,UI层引用BLL层但不引用DAL层,而对于DAL、BLL和UI这三层,都是需要引用Model实体层的,但是通常情况下BLL层并不使用实体所以大部分情况下都不会引用Model层,解释到这里,我觉得我们应该可以很清晰的理解三层架构的框架了,那接下来我就直接讲解我的folder项目了。
1、下图是我的项目的文件图
FolderBLL:逻辑层,引用数据层;
FolderDAL:数据层,直接操作数据库;
FolderEntity:实体层,数据库的字段属性;
Web:UI层,整个程序的界面。
2、这个是vs的解决方案截图
3、UI层
这个只是一个aspx文件,简单的HTML代码我就不详细讲解了,代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FolderDefault.aspx.cs" Inherits="HuaweiSoftware.Folder.Web.FolderDefault" %><!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> <style type="text/css"> html, body { height:100%; width:100%; } </style></head><body style="margin:0 auto;text-align:center"> <form id="form1" runat="server"> <div style="width:100%;height:100%; margin:0 auto;position:fixed"> <div style="width:100%;height:1%"> <div style="float:left;margin-left: 0px;width:80%;height:100%;margin-top:3px;margin-left:3px"> <asp:TextBox ID="txtFilePath" runat="server" Width="100%" BorderColor="#7B7B7B" BorderWidth="1px"></asp:TextBox> </div> <div style="width:19%;height:100%;float:right;text-align:left"> <asp:Button ID="btnSave" runat="server" Text="保存" onclick="btnSave_Click" /> <asp:Button ID="btnLoad" runat="server" Text="加载" onclick="btnLoad_Click" /> </div> </div> <br /> <div style="float:left;width:100%;height:95%;position:absolute;margin-top:3px"> <div style="float:left;width:25%;height:100%;margin:3px" > <asp:TreeView ID="fileNameTree" runat="server" Height="100%" BorderStyle="Solid" Width="100%" BorderWidth="1px" Font-Size="Large" style="overflow:scroll" ImageSet="WindowsHelp" onselectednodechanged="fileNameTree_SelectedNodeChanged" ExpandDepth="0" ForeColor="Black" BorderColor="#7B7B7B"> <HoverNodeStyle BackColor="#3399FF" ForeColor="White" /> <LeafNodeStyle NodeSpacing="5px" /> <NodeStyle NodeSpacing="5px" /> <SelectedNodeStyle BackColor="#3399FF" ForeColor="White" /> </asp:TreeView> </div> <div style="float:left;margin:3px; width: 73%; height: 100%; border:1px solid #7B7B7B;overflow:scroll"> <asp:GridView ID="gvFileMessage" runat="server" Width="100%" EnableModelValidation="True" Font-Bold="False" Font-Names="Calisto MT" Font-Size="Small" AutoGenerateColumns="False" GridLines="None" HorizontalAlign="Left"> <Columns> <asp:BoundField DataField="Name" HeaderText="文件名" /> <asp:BoundField DataField="CreateDate" HeaderText="创建时间" /> <asp:BoundField DataField="ModifyDate" HeaderText="修改时间" /> <asp:BoundField DataField="Type" HeaderText="文件类型" /> <asp:BoundField DataField="Size" HeaderText="文件大小" /> </Columns> <HeaderStyle BackColor="#F0F0F0" Height="30px" HorizontalAlign="Left" VerticalAlign="Middle" Font-Size="Medium" ForeColor="#686868" /> <RowStyle HorizontalAlign="Left" Font-Size="Medium" ForeColor="#3E3E42" Height="30" /> </asp:GridView> </div> </div> </div> </form></body></html>HTML和css我也只是接触到基础,而且也不难学,所以我就只是把代码放上来就好了,下面的就是后台代码
4、.aspx.cs
我这里是直接用system.IO这个库的directoryInfo类来获取文件夹目录,用fileInfo类来获取文件,都是通过本地文件路径获取的,代码如下
using System;using System.Collections.Generic;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.IO;using System.Data;using HuaweiSoftware.Folder.FolderBLL;using HuaweiSoftware.Folder.FolderEntity;namespace HuaweiSoftware.Folder.Web{ public partial class FolderDefault : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { btnLoad_Click(sender, e); if (fileNameTree.Nodes.Count != 0) { fileNameTree.Nodes[0].Selected = true; fileNameTree_SelectedNodeChanged(sender, e); } } } /// <summary> /// 保存 /// </summary> protected void btnSave_Click(object sender, EventArgs e) { GetFileInfo getfileInfo = new GetFileInfo(); if (txtFilePath.Text != "") { FolderBll bll = new FolderBll(); bll.ClearData(); //判断路径是否存在 if (Directory.Exists(txtFilePath.Text)) { List<FolderInfo> folderList = bll.GetFolders(); List<FolderInfo> filepathlist = new List<FolderInfo>(); string[] str = txtFilePath.Text.Split('\\'); int leveldif = str.Length; int seq = 0; if (folderList.Count > 0) { seq = folderList[folderList.Count - 1].Seq; } FolderInfo folderRoot = getfileInfo.GetFilesInfo(filepathlist, txtFilePath.Text, seq, leveldif); filepathlist.Add(folderRoot); List<FolderInfo> fileList = getfileInfo.GetAllDirectories(filepathlist, txtFilePath.Text, seq, leveldif); bll.InsertData(fileList); } else { Response.Write("<script>alert('输入的路径不正确!');history.back();</script>"); } txtFilePath.Text = ""; } else { Response.Write("<script>alert('请输入路径!');history.back();</script>"); } } /// <summary> /// 把数据加载到树 /// </summary> protected void btnLoad_Click(object sender, EventArgs e) { fileNameTree.Nodes.Clear(); FolderBll bll = new FolderBll(); List<FolderInfo> folderList = bll.GetFolders(); TreeViewBinding(folderList, null); } /// <summary> /// 加载文件信息gridview中 /// </summary> protected void fileNameTree_SelectedNodeChanged(object sender, EventArgs e) { FolderBll bll = new FolderBll(); GetFileInfo getInfo = new GetFileInfo(); TreeNodeCollection nodes = fileNameTree.SelectedNode.ChildNodes; DataTable dt = getInfo.GetDatable(nodes); if (dt.Rows.Count == 0) { dt.Rows.Add(dt.NewRow()); } gvFileMessage.DataSource = dt; gvFileMessage.DataBind(); } /// <summary> /// treeview绑定数据 /// </summary> /// <param name="folderInfo">数据表的list集合</param> /// <param name="p_Node">前一个已添加的节点</param> protected void TreeViewBinding(List<FolderInfo> folderInfo, TreeNode p_Node) { //筛选数据 List<FolderInfo> listInfo = folderInfo.FindAll(delegate(FolderInfo filterlist) { if (p_Node != null) { return filterlist.ID == Convert.ToInt32(p_Node.Value) + 1; } else { return filterlist.Seq == 1; } }); //循环递归 foreach (FolderInfo item in listInfo) { TreeNode node = new TreeNode(); node.Value = item.ID.ToString(); node.Text = item.Name; //如果父节点为空或者是第一级节点 if (p_Node == null || item.Level == 0) { fileNameTree.Nodes.Add(node); TreeViewBinding(folderInfo, node); } //级数比上一个添加的节点级数大 else if (item.Level > Convert.ToInt32(p_Node.Depth) && item.ID > Convert.ToInt32(p_Node.Value)) { p_Node.ChildNodes.Add(node); TreeViewBinding(folderInfo, node); } //级数和上一个添加的节点级数相等 else if (item.Level == Convert.ToInt32(p_Node.Depth)) { p_Node.Parent.ChildNodes.Add(node); TreeViewBinding(folderInfo, node); } //级数比上一个添加的节点的级数小 else { p_Node.Parent.Parent.ChildNodes.Add(node); TreeViewBinding(folderInfo, node); } } } }}我不希望后台的代码太繁琐,所以把可以简化调用的代码都整理好放到了另一个类中,而这个类我就直接添加在Web这个类库里了,代码如下
using System;using System.Collections.Generic;using System.IO;using System.Web;using System.Data;using HuaweiSoftware.Folder.FolderEntity;using HuaweiSoftware.Folder.FolderBLL;using System.Web.UI.WebControls;namespace HuaweiSoftware.Folder.Web{ public class GetFileInfo { /// <summary> /// 递归获取要添加到表的文件实体集合 /// </summary> /// <param name="txtFilePath">文件路径</param> /// <param name="seq">当前需要插入的顺序</param> /// <returns></returns> public List<FolderInfo> GetAllDirectories(List<FolderInfo> filepathlist, string txtFilePath, int seq,int leveldif) { string[] subPaths = Directory.GetDirectories(txtFilePath);//得到所有子目录 for (int i = 0; i < subPaths.Length; i++) { FolderInfo dirInfo = GetFilesInfo(filepathlist, subPaths[i], seq, leveldif); filepathlist.Add(dirInfo); //递归调用 seq = filepathlist[filepathlist.Count - 1].Seq; GetAllDirectories(filepathlist, subPaths[i], seq, leveldif); } string[] files = Directory.GetFiles(txtFilePath); for (int j = 0; j < files.Length; j++) { FolderInfo filesInfo = GetFilesInfo(filepathlist, files[j], seq, leveldif); filepathlist.Add(filesInfo); } return filepathlist; } /// <summary> /// 获取每一条路径的实体 /// </summary> /// <param name="filepathlist">需要插入的实体集合</param> /// <param name="txtFilePath">文件路径</param> /// <param name="seq">当前需要插入的顺序</param> /// <returns></returns> public FolderInfo GetFilesInfo(List<FolderInfo> filepathlist, string txtFilePath,int seq,int leveldif) { FolderInfo entity = new FolderInfo(); string[] str = txtFilePath.Split('\\'); entity.Level = str.Length - leveldif; if (filepathlist.Count > 0) { seq = filepathlist[filepathlist.Count - 1].Seq; } entity.Seq = seq + 1; entity.Name = str[str.Length - 1]; entity.CreateDate = DateTime.Now; entity.ModifyDate = DateTime.Now; entity.Type = "文件类"; entity.Size = 0; return entity; } /// <summary> /// gridview获取数据表 /// </summary> /// <param name="nodes">当前选择节点子节点</param> /// <returns></returns> public DataTable GetDatable(TreeNodeCollection nodes) { FolderBll bll = new FolderBll(); DataTable dt = bll.GetDatable(); DataView dv = new DataView(dt); DataTable dvTbl = dt.Clone(); for (int i = 0; i < nodes.Count;i++ ) { dv.RowFilter = "ID = " + nodes[i].Value; DataTable dat = dv.ToTable(); DataRow dw = dat.Rows[0]; dvTbl.Rows.Add(dw.ItemArray); } return dvTbl; } }}5、BLL层
因为只是一个比较简单的小程序,需要用到的函数并不多,所以我在这一层只创建了一个类,代码如下
using System;using System.Collections.Generic;using System.Text;using System.Web;using System.Data;using System.Data.SqlClient;using System.Web.UI.WebControls;using HuaweiSoftware.Folder.FolderDAL;using HuaweiSoftware.Folder.FolderEntity;namespace HuaweiSoftware.Folder.FolderBLL{ public class FolderBll { /// <summary> /// 添加数据到表 /// </summary> /// <param name="folderList">需要添加的实体集合</param> public void InsertData(List<FolderInfo> folderList) { FolderDal dal = new FolderDal(); dal.InsertData(folderList); } /// <summary> /// 获取表的数据 /// </summary> /// <returns>数据表的实体集合</returns> public List<FolderInfo> GetFolders() { FolderDal dal = new FolderDal(); List<FolderInfo> folderInfo = new List<FolderInfo>(); folderInfo = dal.GetFolders(); return folderInfo; } /// <summary> /// 获取文件数据表 /// </summary> /// <param name="id"></param> /// <returns></returns> public DataTable GetDatable() { FolderDal dal = new FolderDal(); DataTable dt = dal.GetDatable(); return dt; } /// <summary> /// 清空数据表 /// </summary> public void ClearData() { FolderDal dal = new FolderDal(); dal.ClearData(); } }}BLL层的函数都是调用DAL层的,所以各个函数我在下面的DAL层里再详细讲解吧
6、DAL层
在这一层,我创建了两个类,一个负责直接操作数据库,一个是传SQL语句的,跟我之前的silverlight的那个一样,代码如下
using System;using System.Collections.Generic;using System.Text;using System.Data;using System.Data.SqlClient;using HuaweiSoftware.Folder.FolderEntity;namespace HuaweiSoftware.Folder.FolderDAL{ public class FolderDal { private SqlConnection m_Connection; /// <summary> ///构造函数 /// </summary> public FolderDal() { m_Connection = new SqlConnection(DBHelper.ConnectionString); } /// <summary> /// 向数据表添加文件 /// </summary> /// <param name="folderList">需要添加的实体集合</param> public void InsertData(List<FolderInfo> folderList) { string sqlString = "INSERT INTO Folder VALUES(@Level,@Seq,@Name,@CreateDate,@ModifyDate,@Type,@Size)"; for (int i = 0; i < folderList.Count; i++) { SqlParameter[] par = new SqlParameter[] { new SqlParameter("@Level",SqlDbType.Int){ Value = folderList[i].Level }, new SqlParameter("@Seq",SqlDbType.Int){ Value = folderList[i].Seq }, new SqlParameter("@Name",SqlDbType.NVarChar,50){ Value = folderList[i].Name }, new SqlParameter("@CreateDate",SqlDbType.DateTime){ Value = folderList[i].CreateDate }, new SqlParameter("@ModifyDate",SqlDbType.DateTime){ Value = folderList[i].ModifyDate }, new SqlParameter("@Type",SqlDbType.NVarChar,50){ Value = folderList[i].Type }, new SqlParameter("@Size",SqlDbType.Int){ Value = folderList[i].Size } }; DBHelper.ExecuteNonQuery(m_Connection, sqlString, par); m_Connection.Close(); } } /// <summary> /// 获取数据表 /// </summary> /// <returns></returns> public DataTable GetDatable() { string sqlString = "SELECT * FROM Folder ORDER BY Seq"; DataTable folderTbl = DBHelper.ExecuteDataTable(m_Connection, sqlString); return folderTbl; } /// <summary> /// 取出数据表的文件 /// </summary> /// <returns>数据表的实体集合</returns> public List<FolderInfo> GetFolders() { List<FolderInfo> folderInfo = new List<FolderInfo>(); DataTable folderTbl = GetDatable(); foreach (DataRow row in folderTbl.Rows) { FolderInfo entity = new FolderInfo(); entity.ID = (int)row["ID"]; entity.Level = (int)row["Level"]; entity.Seq = (int)row["Seq"]; entity.Name = (string)row["Name"]; folderInfo.Add(entity); } return folderInfo; } /// <summary> /// 清空数据表 /// </summary> public void ClearData() { string sqlString = "TRUNCATE TABLE Folder"; DBHelper.ExecuteNonQuery(m_Connection,sqlString); m_Connection.Close(); } }}由于另外一个类DBHelper.cs我是直接在两个项目中使用的,所以如果你有需要的话可以参考我的上一篇文章“【Silverlight】模仿Windows资源管理器的folder项目”里的同一个类,代码是一样的,我这里就不再次上传代码了,我说说几个函数的作用吧,InsertData 是向数据库插入前面获得的目录的list集合,GetDatatable 是获取整个数据表以便其他函数的调用,而不至于要常常对数据库进行操作从而增加代码的工作量,GetFolder 是获取选中节点的数据并存到list集合中,最后要说的是ClearData ,因为每次都只保存一个文件夹,所以每次保存都要把上次保存的文件清空,但是如果用delete的话就仅仅把数据清空,而ID并不是从新开始,这就使得整个表并不整洁和完整,所以我用的SQL语句是truncate,当需要重新插入数据的时候ID是再次从零开始的
到这里我的项目已经完成了,我对c#的知识的理解算是从这个项目开始的,所以我才急着要记录下来,都说搞技术很枯燥,但是我很喜欢那种做出东西来之后的那种成就感,所以我会继续努力,所有东西都不熟一蹴而就的,可能我的文章并不是特别的好,但还是希望我的这么点点的知识能帮到你~~
- C#三层架构的Folder项目
- 【三层】三层架构开发项目
- 浅析C#中三层架构的实现
- 浅析C#中三层架构的实现
- C# 最简单的三层架构实例
- c#基于sqlserver数据库的三层架构
- C#三十六 三层架构的实现
- c# 三层架构
- c# 三层架构
- C# 三层架构
- 深入浅出C#三层架构
- C#三层架构详解
- 深入浅出C#三层架构
- 深入浅出C#三层架构
- c#三层架构
- C#三层架构
- C#三层架构思路
- C#三层架构总结
- Redis(二)复制和哨兵
- Jtester的使用
- MDK5 keil 下动态内存分配以及使用事例
- mysql多实例的安装和管理(一台服务器上运行两个mysql实例)
- Objective-c - 私有属性和真私有属性
- C#三层架构的Folder项目
- 简单的酷跑游戏制作思路
- AndroidStudio的JNI开发中遇到的一些问题
- 总结java中的类名对于理解程序的干扰和对策:
- Mybatis框架篇
- MySQL数据类型和常用字段属性总结
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
- 网站升级https
- bzoj 2006 [NOI2010]超级钢琴 二分答案 可持久化线段树