项目搭建流程:
①、建立DTO、Service、UI(AdminWeb和FrontWeb,这里的UI都是MVC项目)、CommonHelper
②、在Service安装EntityFramework,不配置。在UI安装EntityFramework,要配置(UI为入口程序需要调用Service、DTO、CommonHelper)。
在web.config中进行如下配置。
<connectionStrings> <add name="connstr" connectionString="Data Source=.;Initial Catalog=****;User ID=****;Password=****" providerName="System.Data.SqlClient" /> </connectionStrings>
②、配置log4net。在Service安装log4net,不配置。在UI安装log4net并配置。
<log4net> <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --> <!-- Set root logger level to ERROR and its appenders --> <root> <level value="DEBUG" /> <appender-ref ref="RollingFileTracer" /> </root> <!-- Print only messages of level DEBUG or above in the packages --> <appender name="RollingFileTracer" type="log4net.Appender.RollingFileAppender,log4net"> <param name="File" value="App_Data/Log/" /> <param name="AppendToFile" value="true" /> <param name="RollingStyle" value="Date" /> <param name="MaxSizeRollBackups" value="10" /> <param name="MaximumFileSize" value="1MB" /> <param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> </layout> </appender> </log4net>
③、搭建 ExceptionFilter 打印到 Log4Net 未处理异常 :
首先在App_Start下添加一个类叫ExceptionFilter
public class ExceptionFilter:IExceptionFilter { private static ILog log = LogManager.GetLogger(typeof(ExceptionFilter)); public void OnException(ExceptionContext filterContext) { log.Error("出现未处理异常", filterContext.Exception); } }
其次,在Global中加上
log4net.Config.XmlConfigurator.Configure();
④、把 EF 的日志通过Debug 方式打印到 Log4Net。其中的原理参考https://www.cnblogs.com/hdwgxz/p/8487945.html
在Service的的***DBContex中的构造函数中加一句:
public ***DbContext():base("name=connStr") { this.Database.Log = (sql) => { log.DebugFormat("EF执行SQL:{0}", sql); }; }
这行代码的意思:Set this property to log the SQL generated by the System.Data.Entity.DbContext to the given delegate。翻译成中文就是,设定这个属性去把通过System.Data.Entity.DbContext 产生的SQL语句记录下来,然后交个一个委托。通过占位符,性能可以得到优化。
⑤、编写公共实体父类BaseEntity:
public abstract class BaseEntity { public long Id { get; set; } public DateTime CreateDateTime { get; set; } = DateTime.Now; public bool IsDeleted { get; set; } = false; }
⑥、编写其他实体类,并进行属性、关系配置,都要继承BaseEntity,不然就会出现one or more validation errors were detected during model generation.报错字样。
⑦、开发BaseServic(不要声明为public)
class BaseService<T> where T:BaseEntity { private ZSZDbContext ctx; public BaseService(ZSZDbContext ctx) { this.ctx = ctx; } public IQueryable<T> GetAll() { return ctx.Set<T>().Where(e => e.IsDeleted == false); } public long GetTotalCount() { return GetAll().LongCount(); } public IQueryable<T> GetPagedData(int startIndex,int count) { return GetAll().OrderBy(e => e.CreateDateTime).Skip(startIndex).Take(count); } public T GetById(long id) { return GetAll().Where(e => e.Id == id).SingleOrDefault(); } public void MarkDeleted(long id) { var data = GetById(id); data.IsDeleted = true; ctx.SaveChanges(); } }
⑧、配置进程外session(UI层),将session保存到数据库。
运行cmd,到C:\Windows\Microsoft.NET\Framework\v4.0.30319中,然后执行 aspnet_regsql.exe -U sa -P 123456 -ssadd -sstype c -d sales(sales为数据库名)https://www.cnblogs.com/linyongqin/articles/4562434.html
⑨、配置TrimAndDBCModelBinder (截取空格、全角转半角),在CommonHelper中创建。DefaultModelBinder一定要继承自来自System.Web.Mvc
public class TrimToDBCModelBinder:DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { object value = base.BindModel(controllerContext, bindingContext); if (value is string) { string strValue = (string)value; string value2 = ToDBC(strValue).Trim(); return value2; } else { return value; } } /// <summary> 全角转半角的函数(DBC case) </summary> /// <param name="input">任意字符串</param> /// <returns>半角字符串</returns> ///<remarks> ///全角空格为12288,半角空格为32 ///其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248 ///</remarks> private static string ToDBC(string input) { char[] c = input.ToCharArray(); for (int i = 0; i < c.Length; i++) { if (c[i] == 12288) { c[i] = (char)32; continue; } if (c[i] > 65280 && c[i] < 65375) { c[i] = (char)(c[i] - 65248); } } return new string(c); } }
然后在UI的Global中添加
ModelBinders.Binders.Add(typeof(string), new TrimToDBCModelBinder()); ModelBinders.Binders.Add(typeof(int), new TrimToDBCModelBinder()); ModelBinders.Binders.Add(typeof(long), new TrimToDBCModelBinder()); ModelBinders.Binders.Add(typeof(double), new TrimToDBCModelBinder());
⑩、项目的前台后台都配置上AutoFac。在UI安装 Install-Package Autofac.Mvc5 。在Global中调用:
var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();//把当前 程序集中的 Controller 都注册 //不要忘了.PropertiesAutowired() // 获取所有相关类库的程序集 Assembly[] assemblies = new Assembly[] { Assembly.Load("ZSZ.Service") }; builder.RegisterAssemblyTypes(assemblies) .Where(type => !type.IsAbstract) .AsImplementedInterfaces().PropertiesAutowired(); var container = builder.Build(); //注册系统级别的 DependencyResolver,这样当 MVC 框架创建 Controller 等对象的时候都是管 Autofac 要对象。 DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
最后、套用后台模板。
注意点:
第一、返回IQueryable比IEnumerable好,因为IEnumerable的数据的操作都是在内存中。
第二、IQueryable数据要先OderBy才能Skip、Take。
第三、写modelbinder时未能找到System.Web.Mvc。解决方法:引用的具体路径为:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_4.0.0.1__31bf3856ad364e35
第四、快速实现接口快捷键alt+shift+f10。
第五、发生生成错误,是否继续上次...点击否=>错误列表=>输出。