public class RuleViolation {
public string ErrorMessage { get; private set; } public string PropertyName { get; private set; }
public RuleViolation(string errorMessage) { ErrorMessage = errorMessage; }
public RuleViolation(string errorMessage, string propertyName) { ErrorMessage = errorMessage; PropertyName = propertyName; } }
在写action的时候,捕获SubmitChanges操作的异常,然后给ModelState里添加自定义验证逻辑的异常,ModelState会把添加进去的异常传递给View层,供View层使用。
复制代码 代码如下: try { var db = new BBSDbContext(GlobalHelper.Conn); post.PostUser = User.Identity.Name; //其它赋值操作 db.BBSPosts.InsertOnSubmit(post); db.SubmitChanges(); ModelState.Clear(); } catch (Exception ex) { ModelState.AddModelErrors(post.GetRuleViolations()); ModelState.AddModelError("exception", ex); } 默认的ModelState没有AddModelErrors方法,只有AddModelError方法,我们是后来给他加了一个扩展方法,如下 public static class ModelStateHelpers { public static void AddModelErrors(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors) { foreach (RuleViolation issue in errors) { modelState.AddModelError(issue.PropertyName, issue.ErrorMessage); } } }
在View层使用了Html.ValidationMessage方法在合适的位置输出错误描述,如果View呈现的时候ModelState里有错误的话,会自动显示相应的错误描述,代码示例如下。
复制代码 代码如下: <p> <label for="Title"> 标题:</label> <%= Html.TextBox("Title", null, new { style = "width:700px;" })%> <%= Html.ValidationMessage("Title") %> </p> <p> <label for="Content"> 内容:</label> <%= Html.TextArea("Content", null, new { style = "width:700px;height:100px;" })%> <%= Html.ValidationMessage("Content")%> </p>
5、LINGQ TO SQL的分页
SQLSERVER 2005有很强悍的分页函数,LINQ TO SQL对其有很好的支持,IQueryable<T>的Skip和Take方法最终就生成分页的SQL,先写如下的一个帮助类(取自NerdDinner),这个类的属性很简单,见名知意,就不介绍了。
复制代码 代码如下: public class PaginatedList<T> : List<T> {
public int PageIndex { get; private set; } public int PageSize { get; private set; } public int TotalCount { get; private set; } public int TotalPages { get; private set; }
public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize) { PageIndex = pageIndex; PageSize = pageSize; TotalCount = source.Count(); TotalPages = (int) Math.Ceiling(TotalCount / (double)PageSize);
this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize)); //这句会停止延迟加载,把数据加载到内存里 }
public bool HasPreviousPage { get { return (PageIndex > 0); } }
public bool HasNextPage { get { return (PageIndex+1 < TotalPages); } } }
使用起来很简单,用LINQ TO SQL得到一个IQueryable后,再用其New一个PaginatedList就表示一个已分页的数据集了
复制代码 代码如下: var posts = from post in db.BBSPosts where post.CategoryID == id && post.ParentID == 0 orderby post.PostID descending select post; const int pageSize = 10; var pagePosts = new PaginatedList<BBSPost>(posts, page ?? 0, pageSize); return View(pagePosts);
posts是用linq to sql生成的一个IQueryable<BBSPost>对象,这时候SQL语句并没有执行,会延迟执行,再new一个PaginatedList<BBSPost>的时候会对其生成的SQL语句进行修改,最后把pagePosts传递给view层用就行了,View层我们使用了强类型的View,如下 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SimpleBBS.Helpers.PaginatedList<SimpleBBS.Models.BBSPost>>" %> 页面上要显示上一页,下一页的链接,写起来也很简单
复制代码 代码如下: <div> <% if (Model.HasPreviousPage) { %> <%= Html.RouteLink("上一页", "Default", new { page=(Model.PageIndex-1) }) %> <% } %> <% if (Model.HasNextPage) { %> <%= Html.RouteLink("下一页", "Default", new { page = (Model.PageIndex + 1) })%> <% } %> </div>
6、查看LINQ TO SQL生成的SQL语句?
有人怀疑LINQ TO SQL的性能问题,认为它生成的语句不靠谱,其实它生成的语句都是参数化查询,一般的基于主键或者索引列的查询及大多数更新操作性能应该不会比手写SQL差,如果还是不放心的话,可以把LINQ TO SQL生成的SQL打印出来,以避免性能查的语句产生。 如下代码
复制代码 代码如下: (编辑:威海站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|