跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)
本文转载自:http://www.cnblogs.com/poorboy/archive/2009/09/03/1559925.html
功能:
1.用户登录后显示最近记账列表
2.用户可以随时记账(时间、账目类型、收入OR支出、金额、地点、内容等)
3.智能搜索
4.各种统计
5.能够到处EXCEL表格
功能比较简单,用例图就不画啦,直接设计数据库。
现在我们直接进行数据库建模,建模工具是EA,
数据库模型图:

Users:用户表
Accounts:账目表
AccountsTypes:账目类型表(衣食住行等)
接下来开始建立数据库:
数据库采用SQL SERVER 2000
数据库名称:PBAccount
SQL语句:
View Code
1 CREATE TABLE [Accounts] ( 2 [AccountID] [uniqueidentifier] NOT NULL , 3 [UserID] [uniqueidentifier] NOT NULL , 4 [InOrOut] [bit] NOT NULL , 5 [Amount] [float] NOT NULL , 6 [TypeID] [uniqueidentifier] NOT NULL , 7 [Time] [datetime] NOT NULL , 8 [Status] [int] NOT NULL , 9 [Detail] [image] NULL , 10 CONSTRAINT [PK_Accounts] PRIMARY KEY CLUSTERED 11 ( 12 [AccountID] 13 ) ON [PRIMARY] , 14 CONSTRAINT [FK_Accounts_AccountTypes] FOREIGN KEY 15 ( 16 [TypeID] 17 ) REFERENCES [AccountTypes] ( 18 [AccountTypeID] 19 ), 20 CONSTRAINT [FK_Accounts_Users] FOREIGN KEY 21 ( 22 [UserID] 23 ) REFERENCES [Users] ( 24 [UserID] 25 ) 26 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 27 GO 28 29 CREATE TABLE [AccountTypes] ( 30 [AccountTypeID] [uniqueidentifier] NOT NULL , 31 [AccountTypeName] [char] (20) COLLATE Chinese_PRC_CI_AS NOT NULL , 32 CONSTRAINT [PK_AccountTypes] PRIMARY KEY CLUSTERED 33 ( 34 [AccountTypeID] 35 ) ON [PRIMARY] 36 ) ON [PRIMARY] 37 GO 38 39 CREATE TABLE [Users] ( 40 [UserID] [uniqueidentifier] NOT NULL , 41 [LoginName] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , 42 [Name] [char] (10) COLLATE Chinese_PRC_CI_AS NULL , 43 [Sex] [bit] NULL , 44 [BirthDay] [datetime] NULL , 45 [Profession] [char] (10) COLLATE Chinese_PRC_CI_AS NULL , 46 [Role] [int] NULL , 47 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 48 ( 49 [UserID] 50 ) ON [PRIMARY] 51 ) ON [PRIMARY] 52 GO
注意:一个要设置好各表之间的关系,只有这个才能自动生成正确的ORM,如下图:

OK,数据库设计已经完成,下篇我们接着探讨EF,LINQ和Resposity模式的应用。
我们将以实例为主,关于MVC的具体理论请在博客园中搜索,到处都有。
在设计好数据库之后,打开VS2008,选择创建项目“ASP.NET MVC WEB APLLICATION”,系统会自动生成一个MVC框架,我们在这个MVC框架的基础上开始我们的项目。创建后,我们会不得不佩服微软的贴心,她已经给我们自动生成了一个MVC框架程序,如下图:
看看,是不是“M”“V”“C”都有啦,而且JQUERY 和AJAX也给引入了,实在是让人省心不少啊
运行之后,界面如下:
,不错吧,OK,下面我们开始写入我们自己的东东啦。
首先,我们看到"Mondels"在“Scripts”文件夹下面,看着让人不爽,应该与“M”“V”并列才对啊,所以我们把它移到根目录下面,如下图:
因为我们要用到Repository模式,希望大家对此也要有一定的了解,以下是网友的话:
“
在《企业架构模式》中,译者将Repository翻译为资源库。给出如下说明:
通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调。
在《领域驱动设计:软件核心复杂性应对之道》中,译者将Repository翻译为仓储,给出如下说明:
一种用来封装存储,读取和查找行为的机制,它模拟了一个对象集合。
使用该模式的最大好处就是将领域模型从客户代码和数据映射层之间解耦出来。
”摘自http://www.cnblogs.com/carysun/archive/2009/03/20/repository.html
具体请各位百度一下吧。
现在开始创建所需的文件夹,“Models”文件夹是提供所有实体类的接口,比如“用户”、“账目”等,以及对这些实体类的所有操作功能(增删改查),于是我们首先在“Models”文件夹下创建三个接口,它们分别是"IUser" "IAccount" "IAccountType"作为用户类、账目类和账目类型类的接口,代码如下:
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 namespace PBAccount.Models 6 { 7 public interface IAccount 8 { 9 Guid AccountID { get; set; } 10 IUser user { get; set; } 11 bool InOrOut { get; set; } 12 float Amount { get; set; } 13 IAccountType AccountType { get; set; } 14 DateTime Time { get; set; } 15 AccountStatus Status { get; set; } 16 string Detail { get; set; } 17 } 18 19 /// <summary> 20 /// 账目可见性 21 /// </summary> 22 public enum AccountStatus 23 { 24 /// <summary> 25 /// 私有 26 /// </summary> 27 personal=0, 28 /// <summary> 29 /// 公开 30 /// </summary> 31 open 32 } 33 34 } 35 36 using System; 37 using System.Collections.Generic; 38 using System.Linq; 39 using System.Text; 40 41 namespace PBAccount.Models 42 { 43 public interface IAccountType 44 { 45 Guid AccountTypeID { get; set; } 46 string AccountTypeName { get; set; } 47 } 48 } 49 50 using System; 51 using System.Collections.Generic; 52 using System.Linq; 53 using System.Text; 54 55 namespace PBAccount.Models 56 { 57 public interface IUser 58 { 59 Guid UserID { get; set; } 60 string LoginName { get; set; } 61 string Name { get; set; } 62 bool Sex { get; set; } 63 DateTime BirthDay { get;set;} 64 string Profession { get; set; } 65 int Role { get; set; } 66 67 } 68 }
以上就是三个接口啦,具体内容一看明了.OK,现在还在要Models文件夹下建二个文件夹,它们分别是“User” "Account",这两个文件夹下主要是具体功能的实现。Models里面的东东是不与数据库直接打交道的,我们使用Repository模式来提供与数据库直接打交道的增删查改的操作,Models直接使用Repository提供的基本功能。好了,我们先把Models放在这儿不管,下面来设置Repository模式,首先创建一个Repository文件夹(与Models平级),如下图:
,要与数据库打交道,我们就想到了EF这个ORM,关于EF,请参考:http://www.cnblogs.com/xray2005/archive/2009/05/07/1452033.html ,
打开“服务器资源管理器”,建立与我们创建的数据库的连接,如下图:
,然后,在“Repository”文件夹下面添加“ADO.NET Entity Data Model”,我们命名为“AccountEDM”,
然后选择“从数据库生成”,把我们建立的三个表全选,系统就自动生成了一个EF,如下图:
这一篇就介绍到这儿,下一篇我们具体介绍Repository模式与EF结合在ASP.NET MVC中的应用。
欢迎批评指正。
上篇我们已经构建好了EF模型,本篇我们在这个模型的基础上应用Repository模式。
从现在开始,如果你是菜鸟,一定要仔细的慢慢分析啊,这可是接触到核心了啊,呵呵,吓你呢,其实没有那么难。
第一步,我们要把所有的公共操作抽象出来,无外乎我们多次提到的增删改查等操作,这样以后只要继承这个类就可以了。好,首先,我们在Models文件夹下定义一个IRepository接口,这时候,你可能要问:你怎么知道这个接口的类型啊。你别急,我不知道以后要继承的类是什么类型,但我知道它们基本上都有增删改查的功能,这个时候就要用到大名鼎鼎的泛型啦。代码如下:
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 namespace PBAccount.Models 6 { 7 public interface IRepository<T> 8 { 9 void Add(T entity); 10 void Del(T entity); 11 void Update(T entity); 12 T Find(Guid entityId); 13 IList<T> Find(ICriteria criteria); 14 IList<T> FindAll(); 15 IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr); 16 int Count(ICriteria criteria); 17 void SaveChanges(); 18 } 19 }
看看上面的代码,是不是常用的操作都有了啊,你是不是对 IList<T> Find(ICriteria criteria); 这句有点疑惑啊,其实ICriteria
是我定义的一个查询条件,我们都知道项目中经常有组合查询,那么多的组合条件,写起来比较麻烦而且非常容易出错,比如起止日期、姓名、地点、金额等一大堆组合条件,写起来确实很累人,这时候我就想到何不定义一个条件类呢。另外,我们现实列表的时候还要用到分页,我们在接口中也写好了这个方法,IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);厉害吧,你只要填入条件(criteria)、当前页码(page)、每页条数(pageSize)以及排序条件(orderExpr),那么就可以直接分页显示啦。这个在以后你会发现它的极大的优越性,它与JQuery 的flexigrid (类似GridView控件)的分页显示简直就是珠联璧合。下面代码是ICriteria接口 与 Order类的定义。
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Data.Objects; 6 7 namespace PBAccount.Models 8 { 9 public interface IRepository<T> 10 { 11 void Add(T entity); 12 void Del(T entity); 13 void Update(T entity); 14 T Find(Guid entityId); 15 IList<T> Find(ICriteria criteria); 16 IList<T> FindAll(); 17 IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr); 18 int Count(ICriteria criteria); 19 void SaveChanges(); 20 } 21 22 /// <summary> 23 /// 查询条件类型 24 /// </summary> 25 26 public enum CriteriaType 27 { 28 /// <summary> 29 /// 0 表示查询条件是个表达式 30 /// </summary> 31 Expression = 0, 32 /// <summary> 33 /// 1表示查询条件是个参数 34 /// </summary> 35 Parameter = 1 36 } 37 38 /// <summary> 39 /// 查询条件参数类 40 /// </summary> 41 public class CriteriaParameter 42 { 43 /// <summary> 44 /// 参数的值 45 /// </summary> 46 public object Value { get; private set; } 47 /// <summary> 48 /// 参数的名称 49 /// </summary> 50 public string Name { get; set; } 51 /// <summary> 52 /// 参数字段 ?如果你暂时不明白,在以后我们具体使用的时候一看就知道啦,别着急,慢慢来啊 53 /// </summary> 54 public string Field { get; private set; } 55 56 /// <summary> 57 /// 构造函数 58 /// </summary> 59 /// <param name="name"></param> 60 /// <param name="value"></param> 61 /// <param name="field"></param> 62 public CriteriaParameter(string name, object value, string field) 63 { 64 this.Name = name; 65 this.Value = value; 66 this.Field = field; 67 } 68 } 69 70 /// <summary> 71 /// 查询条件接口 72 /// </summary> 73 public interface ICriteria 74 { 75 CriteriaType CriteriaType { get; } 76 string Expression { get; } 77 CriteriaParameter[] Parameters { get; } 78 79 /// <summary> 80 /// 并 操作 比如查询“姓名”+“金额” 等 81 /// </summary> 82 /// <param name="other"></param> 83 /// <returns></returns> 84 85 ICriteria And(ICriteria other); 86 ICriteria Or(ICriteria other); 87 ICriteria Not(); 88 } 89 90 /// <summary> 91 /// 排序类型 92 /// </summary> 93 public enum OrderType 94 { 95 ASC, 96 DESC 97 } 98 99 /// <summary> 100 /// 拍戏类 101 /// </summary> 102 public class Order 103 { 104 public OrderType OrderType { get; set; } 105 /// <summary> 106 /// 排序的字段 107 /// </summary> 108 public string[] Fields { get; set; } 109 public Order(OrderType orderType, params string[] fields) 110 { 111 this.OrderType = orderType; 112 this.Fields = fields; 113 } 114 115 public Order(params string[] fields) : this(OrderType.ASC, fields) { } 116 117 /// <summary> 118 /// 取出排序的表达式 119 /// </summary> 120 public string Expression 121 { 122 get 123 { 124 string str = string.Empty; 125 foreach (var field in Fields) 126 { 127 if (str.Length > 0) 128 str += ","; 129 str += string.Format("it.{0} {1}", field, OrderType.ToString()); 130 } 131 return str; 132 } 133 } 134 135 /// <summary> 136 /// 排序 返回 IQueryable<T> 类型的结果 137 /// </summary> 138 /// <typeparam name="T"></typeparam> 139 /// <param name="query"></param> 140 /// <returns></returns> 141 public IQueryable<T> OrderFrom<T>(ObjectQuery<T> query) where T : class 142 { 143 switch (this.OrderType) 144 { 145 case OrderType.ASC: 146 return query.OrderBy(Expression); 147 case OrderType.DESC: 148 return query.OrderBy(Expression); 149 } 150 return query; 151 } 152 153 } 154 155 156 }
以上就是 IRepository接口以及相关的一些类,这里面涉及到得知识就多了一些,虽然有注释,但是如果以前接触很少的话可能看起来还是比较困难,不过不用着急,下面我再介绍一下啊,这里面你要弄懂两个概念,ObjectQuery 和IQueryable,如果你一点都不明白,那么强烈建议你看看这个
http://www.it.oaod.com/PcTech-73703.html , 另外也要搞清楚 Entity SQL ,参考 http://tech.ddvip.com/2009-05/1242029734118538.html ,了解一个大概就可以啦。
我们定义了ICriteria,现在我们就要对它实现,我们要在Models中创建一个Criteria类继承ICriteria接口,代码如下:
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using PBAccount.Models; 6 7 namespace PBAccount.Models 8 { 9 public abstract class BaseCriteria : ICriteria 10 { 11 public const string FieldPrefix = "it."; 12 public const string NamePrefix = "@"; 13 14 public BaseCriteria() 15 { 16 this.CriteriaType = CriteriaType.Expression; 17 } 18 19 #region ICriteria 成员 20 21 public abstract string Expression { get; } 22 23 24 public ICriteria And(ICriteria other) 25 { 26 return new AndCriteria(this, other); 27 } 28 29 public ICriteria Or(ICriteria other) 30 { 31 return new OrCriteria(this, other); 32 } 33 34 public ICriteria Not() 35 { 36 return new NotCriteria(this); 37 } 38 39 protected List<CriteriaParameter> parameters = new List<CriteriaParameter>(); 40 public CriteriaParameter[] Parameters 41 { 42 get { return parameters.ToArray(); } 43 } 44 45 public CriteriaType CriteriaType 46 { 47 get; 48 protected set; 49 } 50 51 #endregion 52 53 static protected string ParameterNameFormat(string field) 54 { 55 return field.Replace('.', '_'); 56 } 57 } 58 59 public class TrueCriteria : BaseCriteria 60 { 61 public override string Expression 62 { 63 get { return "(1=1)"; } 64 } 65 } 66 67 public class EqualParameterCriteria : BaseCriteria 68 { 69 CriteriaParameter cp; 70 public EqualParameterCriteria(String field, Object value) 71 { 72 this.CriteriaType = CriteriaType.Parameter; 73 cp = new CriteriaParameter(ParameterNameFormat(field), value, field); 74 parameters.Add(cp); 75 } 76 77 public override string Expression 78 { 79 get { return string.Format("{2}{0}={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); } 80 } 81 } 82 83 public class EqualCriteria : BaseCriteria 84 { 85 protected String field; 86 87 protected Object value; 88 89 public EqualCriteria(String field, Object value) 90 { 91 92 this.field = field; 93 94 this.value = value; 95 96 } 97 98 public override string Expression 99 { 100 get 101 { 102 if (value.GetType() == typeof(int) || 103 value.GetType() == typeof(double) || 104 value.GetType() == typeof(bool)) 105 return string.Format("{2}{0}={1}", field, value, FieldPrefix); 106 return string.Format("{2}{0}='{1}'", field, value, FieldPrefix); 107 } 108 } 109 110 } 111 112 public class NotEqualParameterCriteria : BaseCriteria 113 { 114 CriteriaParameter cp; 115 public NotEqualParameterCriteria(String field, Object value) 116 { 117 this.CriteriaType = CriteriaType.Parameter; 118 cp = new CriteriaParameter(ParameterNameFormat(field), value, field); 119 parameters.Add(cp); 120 } 121 122 public override string Expression 123 { 124 get 125 { 126 return string.Format("{2}{0}!={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); 127 } 128 } 129 } 130 131 public class NotEqualCriteria : BaseCriteria 132 { 133 protected String field; 134 135 protected Object value; 136 137 public NotEqualCriteria(String field, Object value) 138 { 139 140 this.field = field; 141 142 this.value = value; 143 144 145 } 146 #region ICriteria 成员 147 148 public override string Expression 149 { 150 get 151 { 152 if (value.GetType() == typeof(int) || 153 value.GetType() == typeof(double) || 154 value.GetType() == typeof(bool)) 155 return string.Format("{2}{0}!={1}", field, value, FieldPrefix); 156 return string.Format("{2}{0}!='{1}'", field, value, FieldPrefix); 157 158 } 159 } 160 161 #endregion 162 } 163 164 public class GreaterThanParameterCriteria : BaseCriteria 165 { 166 CriteriaParameter cp; 167 public GreaterThanParameterCriteria(String field, Object value) 168 { 169 this.CriteriaType = CriteriaType.Parameter; 170 cp = new CriteriaParameter(ParameterNameFormat(field), value, field); 171 parameters.Add(cp); 172 } 173 174 public override string Expression 175 { 176 get 177 { 178 return string.Format("{2}{0}>{3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); 179 } 180 } 181 } 182 183 public class GreaterThanCriteria : BaseCriteria 184 { 185 186 protected String field; 187 188 protected Object value; 189 190 public GreaterThanCriteria(String field, Object value) 191 { 192 193 this.field = field; 194 195 this.value = value; 196 197 } 198 199 #region ICriteria 成员 200 201 public override string Expression 202 { 203 get 204 { 205 if (value.GetType() == typeof(int) || 206 value.GetType() == typeof(double)) 207 return string.Format("{2}{0}>{1}", field, value, FieldPrefix); 208 return string.Format("{2}{0}>'{1}'", field, value, FieldPrefix); 209 210 } 211 } 212 213 #endregion 214 } 215 216 public class GreaterEqualThanParameterCriteria : BaseCriteria 217 { 218 CriteriaParameter cp; 219 public GreaterEqualThanParameterCriteria(String field, Object value) 220 { 221 this.CriteriaType = CriteriaType.Parameter; 222 cp = new CriteriaParameter(ParameterNameFormat(field), value, field); 223 parameters.Add(cp); 224 } 225 226 public override string Expression 227 { 228 get 229 { 230 return string.Format("{2}{0}>={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); 231 } 232 } 233 } 234 235 public class GreaterEqualThanCriteria : BaseCriteria 236 { 237 238 protected String field; 239 240 protected Object value; 241 242 public GreaterEqualThanCriteria(String field, Object value) 243 { 244 245 this.field = field; 246 247 this.value = value; 248 249 } 250 251 #region ICriteria 成员 252 253 public override string Expression 254 { 255 get 256 { 257 if (value.GetType() == typeof(int) || 258 value.GetType() == typeof(double)) 259 return string.Format("{2}{0}>={1}", field, value, FieldPrefix); 260 return string.Format("{2}{0}>='{1}'", field, value, FieldPrefix); 261 } 262 } 263 264 #endregion 265 } 266 267 public class LessThanParameterCriteria : BaseCriteria 268 { 269 CriteriaParameter cp; 270 public LessThanParameterCriteria(String field, Object value) 271 { 272 this.CriteriaType = CriteriaType.Parameter; 273 cp = new CriteriaParameter(ParameterNameFormat(field), value, field); 274 parameters.Add(cp); 275 } 276 277 public override string Expression 278 { 279 get 280 { 281 return string.Format("{2}{0}<{3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); 282 } 283 } 284 } 285 286 public class LessThanCriteria : BaseCriteria 287 { 288 289 protected String field; 290 291 protected Object value; 292 293 public LessThanCriteria(String field, Object value) 294 { 295 296 this.field = field; 297 298 this.value = value; 299 300 } 301 302 #region ICriteria 成员 303 304 public override string Expression 305 { 306 get 307 { 308 if (value.GetType() == typeof(int) || 309 value.GetType() == typeof(double)) 310 return string.Format("{2}{0}<{1}", field, value, FieldPrefix); 311 return string.Format("{2}{0}<'{1}'", field, value, FieldPrefix); 312 } 313 } 314 315 #endregion 316 } 317 318 public class LessEqualThanParameterCriteria : BaseCriteria 319 { 320 CriteriaParameter cp; 321 public LessEqualThanParameterCriteria(String field, Object value) 322 { 323 this.CriteriaType = CriteriaType.Parameter; 324 cp = new CriteriaParameter(ParameterNameFormat(field), value, field); 325 parameters.Add(cp); 326 } 327 328 public override string Expression 329 { 330 get 331 { 332 return string.Format("{2}{0}<={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); 333 } 334 } 335 } 336 337 public class LessEqualThanCriteria : BaseCriteria 338 { 339 340 protected String field; 341 342 protected Object value; 343 344 public LessEqualThanCriteria(String field, Object value) 345 { 346 347 this.field = field; 348 349 this.value = value; 350 351 } 352 353 #region ICriteria 成员 354 355 public override string Expression 356 { 357 get 358 { 359 if (value.GetType() == typeof(int) || 360 value.GetType() == typeof(double)) 361 return string.Format("{2}{0}<={1}", field, value, FieldPrefix); 362 return string.Format("{2}{0}<='{1}'", field, value, FieldPrefix); 363 } 364 } 365 366 #endregion 367 } 368 369 public class LikeCriteria : BaseCriteria 370 { 371 public enum LikeCriteriaType 372 { 373 NoneWildcard, 374 LeftWildcard, 375 RightWildcard, 376 BothWildcard 377 } 378 379 LikeCriteriaType wildcard = LikeCriteriaType.NoneWildcard; 380 381 protected String field; 382 383 protected Object value; 384 385 386 public LikeCriteria(String field, Object value, LikeCriteriaType wildcard) 387 { 388 389 this.field = field; 390 391 this.value = value; 392 393 this.wildcard = wildcard; 394 } 395 396 public LikeCriteria(String field, Object value) : this(field, value, LikeCriteriaType.BothWildcard) { } 397 398 #region ICriteria 成员 399 400 public override string Expression 401 { 402 get 403 { 404 switch (wildcard) 405 { 406 case LikeCriteriaType.NoneWildcard: 407 return string.Format("{2}{0} like '{1}'", field, value, FieldPrefix); 408 case LikeCriteriaType.LeftWildcard: 409 return string.Format("{2}{0} like '%{1}'", field, value, FieldPrefix); 410 case LikeCriteriaType.RightWildcard: 411 return string.Format("{2}{0} like '{1}%'", field, value, FieldPrefix); 412 case LikeCriteriaType.BothWildcard: 413 return string.Format("{2}{0} like '%{1}%'", field, value, FieldPrefix); 414 default: 415 return string.Empty; 416 } 417 } 418 } 419 420 #endregion 421 } 422 423 public class BetweenCriteria : BaseCriteria 424 { 425 string begin_expression; 426 string end_expression; 427 string field; 428 429 430 public BetweenCriteria(String field, string begin_expression, string end_expression) 431 { 432 this.field = field; 433 this.begin_expression = begin_expression; 434 this.end_expression = end_expression; 435 } 436 437 #region ICriteria 成员 438 439 public override string Expression 440 { 441 get 442 { 443 return string.Format("{3}{0} BETWEEN {1} AND {2}", field, begin_expression, end_expression, FieldPrefix); 444 } 445 } 446 447 #endregion 448 449 } 450 451 public class BetweenParameterCriteria : BaseCriteria 452 { 453 CriteriaParameter cp1; 454 CriteriaParameter cp2; 455 456 public BetweenParameterCriteria(string field, object begin_expression, object end_expression) 457 { 458 string fieldPamaName1 = string.Format("{0}1", field); 459 string fieldPamaName2 = string.Format("{0}2", field); 460 461 462 cp1 = new CriteriaParameter(ParameterNameFormat(fieldPamaName1), begin_expression, field); 463 parameters.Add(cp1); 464 cp2 = new CriteriaParameter(ParameterNameFormat(fieldPamaName2), end_expression, field); 465 parameters.Add(cp2); 466 this.CriteriaType = CriteriaType.Parameter; 467 468 } 469 470 public override string Expression 471 { 472 get 473 { 474 return string.Format("{3}{0} BETWEEN {4}{1} AND {4}{2}", cp1.Field, cp1.Name, cp2.Name, FieldPrefix, NamePrefix); 475 } 476 } 477 } 478 479 public class NotCriteria : BaseCriteria 480 { 481 482 protected ICriteria c1; 483 484 public NotCriteria(ICriteria c1) 485 { 486 487 this.c1 = c1; 488 if (c1.CriteriaType == CriteriaType.Parameter) 489 { 490 parameters.AddRange(c1.Parameters); 491 CriteriaType = CriteriaType.Parameter; 492 } 493 } 494 495 #region ICriteria 成员 496 497 public override string Expression 498 { 499 get { return string.Format("NOT({0})", this.c1.Expression); } 500 } 501 502 #endregion 503 } 504 505 public class AndCriteria : BaseCriteria 506 { 507 508 protected ICriteria c1, c2; 509 510 public AndCriteria(ICriteria c1, ICriteria c2) 511 { 512 this.c1 = c1; 513 this.c2 = c2; 514 CriteriaType = c1.CriteriaType | c2.CriteriaType; 515 c1.UniqueCriteriaParameter(c2); 516 if (c1.CriteriaType == CriteriaType.Parameter) 517 parameters.AddRange(c1.Parameters); 518 if (c2.CriteriaType == CriteriaType.Parameter) 519 parameters.AddRange(c2.Parameters); 520 } 521 522 #region ICriteria 成员 523 524 public override string Expression 525 { 526 get { return string.Format("{0} AND {1}", c1.Expression, c2.Expression); } 527 } 528 529 #endregion 530 531 } 532 533 public class OrCriteria : BaseCriteria 534 { 535 536 protected ICriteria c1, c2; 537 538 public OrCriteria(ICriteria c1, ICriteria c2) 539 { 540 this.c1 = c1; 541 this.c2 = c2; 542 CriteriaType = c1.CriteriaType | c2.CriteriaType; 543 c1.UniqueCriteriaParameter(c2); 544 if (c1.CriteriaType == CriteriaType.Parameter) 545 parameters.AddRange(c1.Parameters); 546 if (c2.CriteriaType == CriteriaType.Parameter) 547 parameters.AddRange(c2.Parameters); 548 } 549 550 #region ICriteria 成员 551 552 public override string Expression 553 { 554 get { return string.Format("{0} OR {1}", c1.Expression, c2.Expression); } 555 } 556 557 #endregion 558 559 } 560 561 public static class CriteriaExtentsions 562 { 563 static public void UniqueCriteriaParameter(this ICriteria c1, ICriteria c2) 564 { 565 bool isBothParameter = (c1.CriteriaType & c2.CriteriaType) > 0; 566 if (isBothParameter) 567 { 568 foreach (var p in c1.Parameters) 569 { 570 var it = c2.Parameters.FirstOrDefault(x => x.Name == p.Name); 571 if (it != null) 572 { 573 int index = 1; 574 string testName = it.Name + index.ToString(); 575 while (c2.Parameters.ToList().Exists(x => x.Name == testName) || 576 c1.Parameters.ToList().Exists(x => x.Name == testName)) 577 { 578 ++index; 579 testName = it.Name + index.ToString(); 580 } 581 it.Name = testName; 582 } 583 } 584 } 585 } 586 } 587 }
看到了吧,我们把所有可能的查询条件都给实现啦,以后无论遇到多么复杂的组合查询,我们都不怕啦!
OK,现在我们继续,我们在Repository文件夹下创建一个类BaseRepositoryBase.cs,这个类是要继承IRepository接口,实现里面的方法,这样,就把增删查改方法给抽象出来,以后的类只要继承BaseRepositoryBase.cs,就不用自己去实现啦。
本篇结束,请继续阅读 跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(四)Models(ORM、Repository模式、分页


浙公网安备 33010602011771号