笔记截至20190406
随缘记录
优化: 主键用GUID、交换算法()、分布式(日志、会话状态)
暗灭大人曾经说过,软件开发分成以下几个阶段:
面向功能编程
面向复用编程
面向性能编程
面向未来编程
面向造物编程
CodeFirst优点 不懂数据库都能创建 库和表
EF延时加载 IQueryable IEnumerable(ToList())
单例模式 --> 多个用户会使用同一个EF,且这个EF一直不能释放,EF追踪的数据越来越多,服务器内存迟早爆炸
(联想应用程序池,用户可能会用到被人用过的Application,里面的EF也是被用过的)
线程内唯一 --> 用户使用同一个EF A(new EF,此时还没SaveChanges)-->B(判断线程内有无EF)-->C(判断线程内有无EF)
一次请求 一个EF 用完可以释放
HttpContext.Current.Items["键"] = 值;
↑是线程内唯一
请求结束释放会HttpContext,那EF也被释放了
MVC思想(弱耦合)
web网页-->普通web网页:数据(Model)、模板页(视图)、ashx(控制器)(替换占位符,返回模板页)
aspx 前后端是继承关系 强耦合
HttpModule --> Filter
现在知道为什么 有些写 Http Pipeline 有些写 Named Pipe(无亲缘关系 也能) 进程间的通讯方式~~~
GET、HEAD、PUT、DELETE 幂等
并发操作卡死 --> 不加锁,而是写入队列 + 开一个线程 解决(生产者消费者模型)
约定大于配置(方法-->视图 方法的名称和视图的名称一样)(视图要放在View文件夹下控制器名称下的文件夹)
自动填充 表单name 等于参数 / 表单name 等于 实体类类属性
[HttpPost]特性标签 优先处理post请求 (当方法重载时)
(没被标记的方法用于展示,被标记的方法用于修改,那就不用再同一个方法if else判断了)
数据库有时候 不使用索引的原因:成本比全表扫描还高
使用索引 增加查询速度 但是会消耗硬盘(索引有索引文件)
对索引列的修改删除增加 会比 不增加索引需要更多的资源和时间
1.索引主要用来进行查询的表,设置的索引多一点,可以提高数据库的查询性能。同时因为记录不怎么更新,所以索引比较多的情况下,也不会影响到
更新的速度。
2.经常更新记录的表,如果在一张表中建立过多的索引,则会影响到更新的速度。由于更新操作比较频繁,所以对其的负面影响,要比查询效率提升要
大的多。此时就需要限制索引的数量,只在一些必要的字段上建立索引。
DataFirst用的越来越少 一般是ModelFirst(先分析业务需要什么 再建什么表)(关系-->导航属性)
继承DbContext base("name=连接字符串")
public DbSet<UserInfo> UserInfo{ get; set; }
db.UserInfo.CreateIfNotExists();
普通web网站 ashx 没有命名空间 彼此隔离 共用的类写到App_Code就能共用
aspx 里的ashx 有命名空间 并且代码不用写到App_Code就能共用
工作流
ViewDataDictionary<TModel> ViewData{ get; set;}是ViewPage的一个属性
:原样输出 <a>sdsds</a>
=可以输出标签 sdsds(超链接)
HtmlHelper的扩展方法
<%:Html.ActionLink("显示的字符串", "方法", "控制器", "new { Name = zhangsan }", "new { id = 1, @class = aaa }") %>
返回的是MvcHtmlString(表示不应再继续编码的HTML编码的字符串) 所以可以返回标签
会根据路由规矩自动生成 比如路由规则更改 也会随之更改
/
第一个new是/控制器/方法?Name=zhangsan 第二个new是<a href="/控制器/方法?Name=zhangsan" id="1" class="aaa" >显示的字符串</a>
<%:MvcHtmlString.Create("字符串") %>
最好用:
表单校验 CodeFirst [Require(ErrorMessage="格式错误!")] [RegularExpression("正则表达式")]
还要自动生成 强类型视图
(jQuery.validate和 unobtrusive里会自动把正则表达式添加上)
或者自己用jQuery $('#form1').validate
[A-Za-z\d]+@\w+(\.\w+){1, 2}
后台的可以放在区域里面 Area下有OA文件夹 /OA/UserInfo/Add
用户访问的放在根目录就行 /UserInfo/Show
CheckAttribute : ActionFilterAttribute
[Check] 不用谢Attribute
Razor 强类型视图 @model A.B.UserInfo
@ViewData.Model 就是UesrInfo类型
注释 @*内容*@ 转义@@
@{ @:13212 } 和@MvcHtmlString.Create("标签");
aspx 母版页 cshtml布局页 @RenderBody() RenderSection("xx", true) 默认true @section xx{ <a>dfs</a> } 其他都在body
Route RouteData.Values["Controller"] / ["Action"]
Route -> RouteCollection -> RouteTable(Global.asax)
应用程序池 是一个栈 通过反射 创建Application
UrlRoutingModule(第7~第8个事件)--> MvcRouteHandler 微软自己定义的 普通的Module IHttpModule
源码? Reflector 比如 m = m + 1 --> m++; 外面写m++ 会更快 静态类 = abstract + sealed
ApplicationFactory: 找Global --> 确保Global文件Application_Start调用(路由注册,过滤器注册、Bundle注册等)--> 创建Application
无论使用哪种方式创建表达式对象,编译器都会自动为表达式生成一棵树结构,然后将表达式主体的代码体拆分成单一的表达式并作为主体表达式的子
节点。变量、参数、运算符都会被拆分成一个单一的表达式,如果被拆分的表达式含有多个子表达式,则子表达式将作为表达式的子节并以此类推。
IQueryProvider类拿到Expression表达式树后会对其进行解析以便生成纯SQL语句,再将SQL字符串发送到数据库以便执行
引用的版本 不一致
BaseDal Db.Set<T>().where<T>(Lambda表达式) 当不知道操作哪张表时
数据会话层(工厂类):将BLL与DAL解耦了,提供了一个数据访问的统一访问点
提供一个方法 完成所有数据的保存(一次连接,完成所有操作)(工作单元模式)
DALFactory(内含DbSession) 引用了 DAL
所以不能在DALFactory创建 DbContextFactory(因为那样DAL也要引用DALFactory,会导致循环引用)
(DbContext)CallContext.GetData("字符串");
CallContext.SetData("字符串", 值);
DALFactory --> UserInfoDal(在DbSession中) --> AbstractFactory(在DALFactory内中)反射创建UserInfoDal
简单操作 直接调用Bll
复杂操作 在特定业务类 新建方法 最后再DbSession.Savechanges();
在这过程中可能多次用到DbSession 所以DbSession也需要线程唯一,不要多次new()
注意DbSession(介于业务层和数据层)和DbContext(EF实例)的区别
您觉得我当前最重要的任务是什么(视人而问)
应用程序有Web.config .NET Framework 也有个总的Web.config 文件(UrlRoutingModule 就在里面)
不要忘记把Model层的 连接字符串 放在 Web.config
easy-ui datagrid demo
<table id="tt"></table> 表格
$('#tt').datagrid({ url: /UserInfo/GetLsit, xxx: xxx});
会发送POST请求(也是Ajax) page 和 rows 给服务器
DelFlag 逻辑删除(打上标记,但数据库中没有真正删除)
Sort字段 可以按照Sort排序(如果不想按ID排序)
return Json(new { total = totalCount, rows = UserInfoList });(datagrid规定接收total和rows)
级联删除
总结:所谓的级联更新,就是更新主键表的同时,外键表(grade)同时更新。
所谓的级联删除,就是删除主键表的同时,外键表(grade)同时删除。
var rows = $('#tt').datagrid('getSelections');
var strID ="";
strID += rows[i].ID + ","; 变成1,2,3的格式
strID.substring(0, strID.length - 1);
定义IBLL BLL 批量删除数据
先拿出来 u => list.Contains(u.ID) 避免多次连接数据库(不要调用BLL中简单的删除一条记录保存一次)
if (data = "ok")
{
$('#tt').datagrid.('reload'); //加载表格 不会跳转到第一页(load)
}
删除:
1、拿到ID(1,2,3)
2、业务层(u => list.Contains(u.ID))
3、打上标记后 DbSession.Savachanges();(实际上调用的是EF.SaveChanges())
datagrid(整个是Ajax操作,会记录上一次(删除的)记录,传给服务器(降低性能),所以重新加载表格后,清除历史记录)
$表格.datagrid('clearSelections');
@using(Ajax.BeginForm()){
}
弹出Dialog
$Div.dialog({ 键: 值});
校验表单 $from.validate({ 键: 值});
$AddDiv.submit();
编辑'
1、判断用户是否选择了一行! $.messager.alert('提示', '请选择一行数据', 'error'); return;
2、row[i].ID POST请求拿到需要编辑的数据 return Json(userinfo, JsonRequestBehaviour.AllowGet); 允许get请求
3、给不需要更改的数据添加隐藏域(SubTime和DelFlag) 填充编辑表单(记得转换日期格式,接收到的Json是/Date(毫秒数)/)
4、服务端 UserInfo.Modify = DateTime.Now;
NPOI操作Excel HSSF
问题:业务层和表现层(引用了IBLL)部署在同一台机器上
1、Web Services(服务引用) 或 WCF (表现层和业务层中间加了一层服务层,实现分布式) (表现层和服务层中间 还有一层 门面层)
2、抽象工厂(IoC),通过反射创建 需要A-->容器-->拿到A(不需要知道中间过程)
3、Spring.Net(IoC和DI)(AOP就用过滤器好了,没用Spring里的)
4、Unity(微软推出框架,IoC和DI)
面向接口编程(解耦,多态,规范)
线程槽 隔离机制 线程间 相互独立
rrrrrrrrrrrr
构建搜索 BaseSearch PageIndex PageSize PageCount
多条件查询 var pars = { name: '值', remark: '值' }; loadData(pars) $Table.datagrid({ queryParams: pars })
IoC容器 IApplicationContext
两种方法:配置文件+继承SpringMvcApplication / 容器(读取配置文件new)
调试版本性能差 用Release
Spring用的是Logging日志处理组件(可选单例模式)
xml文件 属性:始终复制到输出目录
过滤器 异常捕获 静态队列(后期可以弄成分布式队列,有些服务器专门做队列服务器) Log4Net
while(true){ 判断队列.Count() 有则写 没有就Sleep(3000); 很关键!!让线程停一会,性能优化}
yyyy-MM-dd
filterContext.HttpContext.Response.Redirect("/Error.html"); -->执行方法后出现异常
filterContext.Result = Redirect(Url.Action("Index", "Login")); -->未执行方法前跳转
所有请求都要得到ActionResult
Log4Net 记录到文件、数据库、邮件等(Log for Net)
Common.Logging和Log4Net 不要using 错了 两个都有 ILog
验证码-返回字节数组 return File(buffer, "image/jpeg");
Session["validateCode"] = null 用完记得设null
控制器 过滤(不方便,只能加载类后面) 和 过滤器过滤(方便,哪里需要加哪里)
ASP.NET请求事件(整体筛选)中 和 ASP.NET MVC过滤器(更灵活 AOP 放哪 筛哪) 相同的名称 没有必然联系?
OA系统功能(/控制器/方法)分布在不同 机器 或者是 同一个OA系统的集群(每次用户登录的时候 找一台空闲的OA机器)
此时就需要分布式存储 Session了
记住密码-->每次登录到的服务器都不同->专门存储Session的服务器-->拿到Session
集群(Web服务器A、B)-->分布式(专门用于存储Session的服务器C)-->Session
A和B的 关系 集群
A、B与C的关系 分布式(A、B都会往C存数据)(Memcached)(如果有多个Memcache,那么就是Memcached集群)
Memcached(存储在内存,速度快,容量小) 是共享的 为了解决共享问题-->每个人都Guid.NewGuid().Tostring(); 当做是SessionID
Memcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。
通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问, 因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似
事情的时候,磁盘开销和阻塞的发生。
没有提供容灾功能,为了性能而放弃
Redis有快照和AOF
半双工(Half Duplex)数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。例如,在一个局域网上使用具有半双工传输的技术,
一个工作站可以在线上发送数据,然后立即在线上接收数据,这些数据来自数据刚刚传输的方向。像全双工传输一样,半双工包含一个双向线路(线路
可以在两个方向上传递数据)。