跟我学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模式、分页

 

posted @ 2013-04-03 13:44  derryliang  阅读(520)  评论(0)    收藏  举报