一个asp.net小项目总结

简介:   写这篇文章之前先吐槽一下,最近换了一个公司,是给一个国企做外包,有两个月了,感觉这里的气氛有点不爽,还有点怀念以前的公司。具体听我说来,这里有几个团队,.net,java,手机开发,.net只有6个人,其他团队都很多人,没办法,这个貌似国际惯例了。

  写这篇文章之前先吐槽一下,最近换了一个公司,是给一个国企做外包,有两个月了,感觉这里的气氛有点不爽,还有点怀念以前的公司。具体听我说来,这里有几个团队,.net,java,手机开发,.net只有6个人,其他团队都很多人,没办法,这个貌似国际惯例了。

  用.net在这里开发一个类似展示信息的系统,是航空公司的运营信息,包括飞机,跑道,地勤,机场等。java做的是飞机排班系统,一听说明白,.net受歧视啊。这个还不是最主要的,我们做的这个系统没有什么重要的逻辑,无非是展示一下表,图等,但是项目经理给我们传达的思想是:他的头头是一个非常有“主见”的老大,对这个系统要求很严格,不断的提出各种新的想法,起初用的telerik控件,底层用的本地webservice+ado.net访问数据,我开始就疑问,这本地的webservice意义何在,还不如直接用ado.net访问呢,还有telerik控件比asp.net控件好看一些,但是效率不怎么样,最终系统中几个重要的页面很慢,部署到服务器中之后访问达不到预期的效果。

  后来改用mvc+easyui,本来也没什么,但是要将easyui中的控件包装成控件,就是直接在cshtml中可以配置,不写js代码这样的,本来mvc也不是很熟,还要包装成easyui标签控件,结果项目进展很缓慢。貌似老大们的IT意识很强,这样做是为了减轻前段程序员的工作量,但是easyui都不熟,包装谈何容易。

  总之两个字:“折腾”。可能这就是国企的特点吧。

  吐槽结束,以上的遭遇让我想起去年给一个大学同学的图书销售公司写的一个小系统,这个主要是为了他们员工使用excel来记录众多繁杂的信息,可以说是一个小的erp系统。技术是最简单易懂的,最直接的,开发速度是比较快的,最后效果是过得去的。在这里跟大家分享一下。

1.需求

主要的模块如下,需求还是很简单的,就是一些对象的增删改查。

1.业务管理,包含图书,客户,业务
2.订单管理,订单编辑,订单搜索
3.人事管理,主要是业务员的工作量
4.系统配置,主要是维护图书销售的区域和学校

 

2.UI设计

  因为他们主要矛盾是解决excel过大造成的操作困难这种最原始的需求,所以对UI没有很高的要求,所以本人不才,自己绣花,结果还算过得去,最起码这个客户他们没有说不好看。截图如下图1。

图1

这里看能看到asp.net默认的实例项目的UI设计,我是在它的基础上做的。每个订单有多个订单子项,这个地方添加订单子项或编辑的时候写了很多的js,,界面如下图2

 

图2

所有的表格都使用了一样的样式,风格是一致的。如下图3

图3

3.代码结构

  这里不敢说用到什么架构,只能说代码结构了。这里采用最常用的三成架构的方式实现功能,可能大家都习以为常了,确实写了这些年的代码,无非都是三层架构的变形,或者底层访问数据使用接口,顶多返回json客户端用js拼接界面,其他的也没有什么了。这里简单地说一下。

  可能和你们一样,也用到了代码实现工具Codematic,这个工具确实好用,节省了不少时间,并且基本的代码结构也实现了。如下图4。

图4

  这个工具已经实现了所有的单表查询,可惜大部分的逻辑都是需要连接查询了,要不然关系数据库就没什么意思了,所以自己写的代码也不少的。

1.数据访问层

数据访问层写了一个动态存储过程,生成分页数据,这里没有把分页放在控件里或者内存中实现,存过过程每次返回固定条数的数据,这样减轻数据量,但是牺牲了一部分新能,动态存储过程每次都执行不同的语句,没法调试性能。还有一点,这里牺牲了一些灵活性,比如每页显示多少航,转到多少页。 调用的存储过程如下:

exec UP_GetRecordByPage 
@tblName1='Orders',
@tblName2='Orders left join MaintainMessage on Orders.MaintainId=MaintainMessage.ID left join Teacher on MaintainMessage.TeacherID=Teacher.ID left join Employee on MaintainMessage.EmployeeID=Employee.ID left join Book on MaintainMessage.BookID=Book.ID left join School on Teacher.SchoolID=School.ID ',
@fldName='Orders.*,Teacher.TeacherName,Employee.Name,Book.Price,Book.BookName,MaintainMessage.OrderStructure',
@OrderfldName='Orders.ID',
@PageSize=20,
@PageIndex=1,
@IsReCount=1,
@OrderType=1,
@strWhere=' 1=1  and School.CityID=1',
@IsPrint=1

存储过程生成的select语句如下:

select top 20 
    Orders.*,Teacher.TeacherName,
    Employee.Name,Book.Price,Book.BookName,
    MaintainMessage.OrderStructure 
from  
    Orders left join MaintainMessage on Orders.MaintainId=MaintainMessage.ID 
    left join Teacher on MaintainMessage.TeacherID=Teacher.ID 
    left join Employee on MaintainMessage.EmployeeID=Employee.ID 
    left join Book on MaintainMessage.BookID=Book.ID 
    left join School on Teacher.SchoolID=School.ID   
where  
    1=1  and School.CityID=1  
order by  Orders.ID  desc
/*----*/ 
select
    count(1) as Total 
from  
Orders 
    left join MaintainMessage on Orders.MaintainId=MaintainMessage.ID 
    left join Teacher on MaintainMessage.TeacherID=Teacher.ID 
    left join Employee on MaintainMessage.EmployeeID=Employee.ID 
    left join Book on MaintainMessage.BookID=Book.ID 
    left join School on Teacher.SchoolID=School.ID   
where  
    1=1  and School.CityID=1

得到数据之后就是很常见的转换成实体类了。

2.业务逻辑层就是将数据返回到展现层,顶多有复杂的数据需要再次访问数据库。如下在一个方法中两次访问数据,需要说的是这种情况如果数据太多会有很多的性能损失,所幸这里数据不多,因为要分页,每次顶多返回20条。

 public List<Erp.Model.Employee> GetEmployeeFerformance(Model.EmpPerformance performance)
        {
            List<Erp.Model.Employee> employees = new List<Model.Employee>();
            SqlParameter[] parameters = {
                                            new SqlParameter("@BeginDate", SqlDbType.DateTime),
                                            new SqlParameter("@EndDate", SqlDbType.DateTime)
                                        };
            parameters[0].Value = performance.BeginDate;
            parameters[1].Value = performance.EndDate;
            DataTable table = DbHelperSQL.RunProcedure("sp_GetEmpPerformance" , parameters , "performance").Tables[0];
            if (table!=null && table.Rows.Count>0)
            {
                for (int i = 0; i < table.Rows.Count; i++)
                {
                    Erp.Model.Employee employee = new Model.Employee();
                    employee.ID = Convert.ToInt32(table.Rows[i]["EmployeeID"].ToString());
                    employee.Name = table.Rows[i]["Name"].ToString();
                    employee.EmployeePerformance.MaintainMessageNum = Convert.ToInt32(table.Rows[i]["MaintainMessageNum"].ToString());
                    employee.EmployeePerformance.CommunicateNum = Convert.ToInt32(table.Rows[i]["CommunicateNum"].ToString());
                    employee.EmployeePerformance.OrdersNum = Convert.ToInt32(table.Rows[i]["OrdersNum"].ToString());
                    employee.EmployeePerformance.TotalAmount = Convert.ToDecimal(table.Rows[i]["TotalAmount"].ToString());
                    employee.EmployeePerformance.TotalRebate = Convert.ToDecimal(table.Rows[i]["TotalRebate"].ToString());
                    SqlParameter[] parametersDetail = {
                                                    new SqlParameter("@BeginDate", SqlDbType.DateTime),
                                                    new SqlParameter("@EndDate", SqlDbType.DateTime),
                                                    new SqlParameter("@EmployeeID", SqlDbType.Int)
                                                      };
                    parametersDetail[0].Value = performance.BeginDate;
                    parametersDetail[1].Value = performance.EndDate;
                    parametersDetail[2].Value = employee.ID;
                    DataSet dsPerformanceDetail = DbHelperSQL.RunProcedure("sp_GetEmpPerformanceNumDetail", parametersDetail, "performanceDetail");
                    if (dsPerformanceDetail != null && dsPerformanceDetail.Tables.Count > 1)
                    {
                        DataTable tbPerformanceDetail = dsPerformanceDetail.Tables[0];
                        if (tbPerformanceDetail != null && tbPerformanceDetail.Rows.Count > 0)
                        {
                            for (int j = 0; j < tbPerformanceDetail.Rows.Count; j++)
                            {
                                employee.EmployeePerformance.MaintainMessageNumDetail += string.Format("{0}:{1} ", tbPerformanceDetail.Rows[j]["BusinessImportance"].ToString(), tbPerformanceDetail.Rows[j]["number"].ToString());
                            }
                        }
                        tbPerformanceDetail = dsPerformanceDetail.Tables[1];
                        if (tbPerformanceDetail != null && tbPerformanceDetail.Rows.Count > 0)
                        {
                            for (int k = 0; k < tbPerformanceDetail.Rows.Count; k++)
                            {
                                employee.EmployeePerformance.CommunicateNumDetail += string.Format("{0}:{1} ", tbPerformanceDetail.Rows[k]["BusinessImportance"].ToString(), tbPerformanceDetail.Rows[k]["number"].ToString());
                            }
                        }
                    }

                    employees.Add(employee);

                }
            }
            return employees;
        }

调用存储过程的实例代码如下:

public DataTable GetTitleList(int currentPage, out int pages, Erp.Model.Employee employee)
        {
            Erp.DAL.PageData pData = new Erp.DAL.PageData();
            pData.TblName1 = "a";
            pData.TblName2 = "Employee a left join EmployeeType b on a.EmployeeTypeID = b.ID left join Employee c on a.ManagerID=c.ID";
            pData.FldName = "a.ID,a.Name,a.UserName,b.TypeName,c.Name as ManagerName,a.Sex,a.Telphone,a.CellPhone,a.QQ,a.Email,a.Statue,a.Remark,a.ManagerID,a.EmployeeTypeID,a.RegionsIDs,a.Password";
            pData.OrderFldName = "a.ID";
            pData.OrderType = 0;
            pData.StrWhere = " 1=1 ";
            pData.PageIndex = currentPage.ToString();
            pData.IsPrint = 1;
            pData.IsReCount = 1;
            pData.PageSize = "20";

            if(employee != null)
            {
                if(!string.IsNullOrEmpty(employee.Name))
                {
                    pData.StrWhere += " and a.Name like '%" + employee.Name + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.Sex))
                {
                    pData.StrWhere += " and a.Sex like '%" + employee.Sex + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.UserName))
                {
                    pData.StrWhere += " and  a.UserName like '%" + employee.UserName + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.Statue))
                {
                    pData.StrWhere += " and  a.Statue like '%" + employee.Statue + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.Email))
                {
                    pData.StrWhere += " and  a.Email like '%" + employee.Email + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.CellPhone))
                {
                    pData.StrWhere += " and  a.CellPhone like '%" + employee.CellPhone + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.QQ))
                {
                    pData.StrWhere += " and  a.QQ like '%" + employee.QQ + "%' ";
                }
                if(!string.IsNullOrEmpty(employee.Telphone))
                {
                    pData.StrWhere += " and  a.Telphone like '%" + employee.Telphone + "%' ";
                }
                if(employee.EmployeeTypeID > 0)
                {
                    pData.StrWhere += " and  a.EmployeeTypeID =  " + employee.EmployeeTypeID.ToString();
                }
                if(employee.ManagerID > 0)
                {
                    pData.StrWhere += " and  a.ManagerID =  " + employee.ManagerID.ToString();
                }
            }

            DataSet dSet = pData.GetPagedData();
            pages = 0;
            if(dSet != null && dSet.Tables != null && dSet.Tables.Count > 0 && dSet.Tables[1] != null && dSet.Tables[1].Rows.Count > 0)
            {
                if(!string.IsNullOrEmpty(dSet.Tables[1].Rows[0]["Total"].ToString()))
                {
                    int items = Convert.ToInt32(dSet.Tables[1].Rows[0]["Total"].ToString());
                    if(items % Convert.ToInt32(pData.PageSize) == 0)
                    {
                        pages = items / Convert.ToInt32(pData.PageSize);
                    }
                    else
                    {
                        pages = items / Convert.ToInt32(pData.PageSize) + 1;
                    }
                }
            }
            return dSet.Tables[0];
        }

3.展现层就更加简单了,一般都是使用“万能的repeater”,没有什么难度。

                <asp:Repeater ID="repEmployees" runat="server" OnItemCommand="repEmployees_ItemCommand">
                    <ItemTemplate>
                        <tr>
                            <td class="r">
                                <%#Eval("ID")%>
                            </td>
                            <td>
                                <%#Eval("Name")%>
                            </td>
                            <td>
                                <%#Eval("UserName")%>
                            </td>
                            <td>
                                <%#Eval("TypeName")%>
                            </td>
                            <td>
                                <%#Eval("ManagerName")%>
                            </td>
                            <td>
                                <%#Eval("Sex")%>
                            </td>
                            <td>
                                <%#Eval("Telphone")%>
                            </td>
                            <td>
                                <%#Eval("CellPhone")%>
                            </td>
                            <td>
                                <%#Eval("QQ")%>
                            </td>
                            <td>
                                <%#Eval("Email")%>
                            </td>
                            <td>
                                <%#Eval("Statue")%>
                            </td>
                            <td>
                                <%#Eval("Remark")%>
                            </td>
                            <td>
                                <asp:HiddenField ID="hidManagerID" runat="server" Value='<%#Eval("ManagerID") %>' />
                                <asp:HiddenField ID="hidEmployeeTypeID" runat="server" Value='<%#Eval("EmployeeTypeID") %>' />
                                <asp:HiddenField ID="hidRegionsIDs" runat="server" Value='<%#Eval("RegionsIDs") %>' />
                                <asp:HiddenField ID="hidPassword" runat="server" Value='<%#Eval("Password") %>' />
                                <asp:LinkButton ID="linEdit" runat="server" Style="padding: 0px;" CommandName="select" CommandArgument='<%#Eval("ID") %>'>编辑</asp:LinkButton>
                            </td>
                        </tr>
                    </ItemTemplate>
                </asp:Repeater>

 

4.总结

这个小项目没有什么出彩的地方,如果大家有用得到类似的,欢迎来联系我。欢迎大家来怕转。

 

 

 

 

 

 

作者:Tyler Ning
出处:http://www.cnblogs.com/tylerdonet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址williamningdong@gmail.com  联系我,非常感谢。

目录
相关文章
|
1月前
|
开发框架 网络协议 .NET
C#/.NET/.NET Core优秀项目和框架2024年10月简报
C#/.NET/.NET Core优秀项目和框架2024年10月简报
|
2月前
|
开发框架 前端开发 API
C#/.NET/.NET Core优秀项目和框架2024年9月简报
C#/.NET/.NET Core优秀项目和框架2024年9月简报
|
3月前
|
开发框架 .NET C#
VSCode开发.net项目时调试无效
【9月更文挑战第22天】在使用 VSCode 开发 .NET 项目时遇到调试问题,可从项目配置、调试配置、调试器安装、运行环境、日志和错误信息等方面排查。确认项目类型及文件配置,检查 `launch.json` 文件及配置项,确保调试器扩展已安装并启用,验证 .NET 运行时版本和环境变量,查看 VSCode 输出窗口和项目日志文件,检查权限及代码错误。若问题仍未解决,可查阅官方文档或社区论坛。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
2月前
|
存储 消息中间件 前端开发
.NET常见的几种项目架构模式,你知道几种?
.NET常见的几种项目架构模式,你知道几种?
|
2月前
|
边缘计算 开发框架 人工智能
C#/.NET/.NET Core优秀项目和框架2024年8月简报
C#/.NET/.NET Core优秀项目和框架2024年8月简报
|
2月前
|
Cloud Native API C#
.NET云原生应用实践(一):从搭建项目框架结构开始
.NET云原生应用实践(一):从搭建项目框架结构开始
|
4月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
51 8
|
4月前
|
架构师 开发者
【悬念揭秘】DDD:那片隐藏在软件深处的业务乐土——.NET项目如何借力领域驱动设计,让复杂业务逻辑迎刃而解?
【8月更文挑战第28天】领域驱动设计(DDD)在.NET项目中的应用聚焦于将业务领域知识与软件开发紧密结合,通过构建清晰的领域模型管理复杂业务逻辑。DDD的核心概念包括限界上下文、聚合、实体等,确保模型与实现的统一。在.NET中,通过CQRS和事件源等模式提高系统响应性和可扩展性,实现业务事件驱动的解耦与协作。DDD不仅是一种设计方法,更是要求开发者深入理解业务的文化,助力.NET项目应对复杂挑战,实现业务与技术的融合。
68 6
|
4月前
|
设计模式 存储 前端开发
揭秘.NET架构设计模式:如何构建坚不可摧的系统?掌握这些,让你的项目无懈可击!
【8月更文挑战第28天】在软件开发中,设计模式是解决常见问题的经典方案,助力构建可维护、可扩展的系统。本文探讨了.NET中三种关键架构设计模式:MVC、依赖注入与仓储模式,并提供了示例代码。MVC通过模型、视图和控制器分离关注点;依赖注入则通过外部管理组件依赖提升复用性和可测性;仓储模式则统一数据访问接口,分离数据逻辑与业务逻辑。掌握这些模式有助于开发者优化系统架构,提升软件质量。
61 5

热门文章

最新文章