分享

跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(三)Models(ORM、Repository模式、分页)

 软件技术与教学 2014-06-15










跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(二)Models(ORM) (9-3 10:43)   
跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(一)数据库建模 (9-1 00:04)

珍惜他人劳动成果,转载请注明出处,谢谢!

上篇我们已经构建好了EF模型,本篇我们在这个模型的基础上应用Repository模式。
从现在开始,如果你是菜鸟,一定要仔细的慢慢分析啊,这可是接触到核心了啊,呵呵,吓你呢,其实没有那么难。
第一步,我们要把所有的公共操作抽象出来,无外乎我们多次提到的增删改查等操作,这样以后只要继承这个类就可以了。好,首先,我们在Models文件夹下定义一个IRepository接口,这时候,你可能要问:你怎么知道这个接口的类型啊。你别急,我不知道以后要继承的类是什么类型,但我知道它们基本上都有增删改查的功能,这个时候就要用到大名鼎鼎的泛型啦。代码如下:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PBAccount.Models
{
    
public interface IRepository<T>
    {
        
void Add(T entity);
        
void Del(T entity);
        
void Update(T entity);
        T Find(Guid entityId);
        IList
<T> Find(ICriteria criteria);
        IList
<T> FindAll();
        IList
<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);
        
int Count(ICriteria criteria);
        
void SaveChanges();
    }
}
复制代码
看看上面的代码,是不是常用的操作都有了啊,你是不是对 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类的定义。
 


复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;

namespace PBAccount.Models
{
    
public interface IRepository<T>
    {
        
void Add(T entity);
        
void Del(T entity);
        
void Update(T entity);
        T Find(Guid entityId);
        IList
<T> Find(ICriteria criteria);
        IList
<T> FindAll();
        IList
<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);
        
int Count(ICriteria criteria);
        
void SaveChanges();
    }

    
/// <summary>
    
/// 查询条件类型
    
/// </summary>

    
public enum CriteriaType
    {
        
/// <summary>
        
/// 0 表示查询条件是个表达式
        
/// </summary>
        Expression = 0,
        
/// <summary>
        
/// 1表示查询条件是个参数
        
/// </summary>
        Parameter = 1
    }

    
/// <summary>
    
/// 查询条件参数类
    
/// </summary>
    public class CriteriaParameter
    {
        
/// <summary>
        
/// 参数的值
        
/// </summary>
        public object Value { getprivate set; }
        
/// <summary>
        
/// 参数的名称
        
/// </summary>
        public string Name { getset; }
        
/// <summary>
        
/// 参数字段 ?如果你暂时不明白,在以后我们具体使用的时候一看就知道啦,别着急,慢慢来啊  
        
/// </summary>
        public string Field { getprivate set; }

        
/// <summary>
        
/// 构造函数
        
/// </summary>
        
/// <param name="name"></param>
        
/// <param name="value"></param>
        
/// <param name="field"></param>
        public CriteriaParameter(string name, object value, string field)
        {
            
this.Name = name;
            
this.Value = value;
            
this.Field = field;
        }
    }

    
/// <summary>
    
/// 查询条件接口
    
/// </summary>
    public interface ICriteria
    {
        CriteriaType CriteriaType { 
get; }
        
string Expression { get; }
        CriteriaParameter[] Parameters { 
get; }

        
/// <summary>
        
/// 并 操作 比如查询“姓名”+“金额” 等
        
/// </summary>
        
/// <param name="other"></param>
        
/// <returns></returns>

        ICriteria And(ICriteria other);
        ICriteria Or(ICriteria other);
        ICriteria Not();
    }

    
/// <summary>
    
/// 排序类型
    
/// </summary>
    public enum OrderType
    {
        ASC,
        DESC
    }

    
/// <summary>
    
/// 拍戏类
    
/// </summary>
    public class Order
    {
        
public OrderType OrderType { getset; }
        
/// <summary>
        
/// 排序的字段
        
/// </summary>
        public string[] Fields { getset; }
        
public Order(OrderType orderType, params string[] fields)
        {
            
this.OrderType = orderType;
            
this.Fields = fields;
        }

        
public Order(params string[] fields) : this(OrderType.ASC, fields) { }

        
/// <summary>
        
/// 取出排序的表达式
        
/// </summary>
        public string Expression
        {
            
get
            {
                
string str = string.Empty;
                
foreach (var field in Fields)
                {
                    
if (str.Length > 0)
                        str 
+= ",";
                    str 
+= string.Format("it.{0} {1}", field, OrderType.ToString());
                }
                
return str;
            }
        }

        
/// <summary>
        
/// 排序 返回  IQueryable<T> 类型的结果
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="query"></param>
        
/// <returns></returns>
        public IQueryable<T> OrderFrom<T>(ObjectQuery<T> query) where T : class
        {
            
switch (this.OrderType)
            {
                
case OrderType.ASC:
                    
return query.OrderBy(Expression);
                
case OrderType.DESC:
                    
return query.OrderBy(Expression);
            }
            
return query;
        }

    }


}
复制代码
以上就是 IRepository接口以及相关的一些类,这里面涉及到得知识就多了一些,虽然有注释,但是如果以前接触很少的话可能看起来还是比较困难,不过不用着急,下面我再介绍一下啊,这里面你要弄懂两个概念,ObjectQuery IQueryable,如果你一点都不明白,那么强烈建议你看看这个
http://www.it./PcTech-73703.html , 另外也要搞清楚 Entity SQL ,参考 http://tech./2009-05/1242029734118538.html ,了解一个大概就可以啦。
我们定义了ICriteria,现在我们就要对它实现,我们要在Models中创建一个Criteria类继承ICriteria接口,代码如下:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using PBAccount.Models;

namespace PBAccount.Models
{
    
public abstract class BaseCriteria : ICriteria
    {
        
public const string FieldPrefix = "it.";
        
public const string NamePrefix = "@";

        
public BaseCriteria()
        {
            
this.CriteriaType = CriteriaType.Expression;
        }

        
#region ICriteria 成员

        
public abstract string Expression { get; }


        
public ICriteria And(ICriteria other)
        {
            
return new AndCriteria(this, other);
        }

        
public ICriteria Or(ICriteria other)
        {
            
return new OrCriteria(this, other);
        }

        
public ICriteria Not()
        {
            
return new NotCriteria(this);
        }

        
protected List<CriteriaParameter> parameters = new List<CriteriaParameter>();
        
public CriteriaParameter[] Parameters
        {
            
get { return parameters.ToArray(); }
        }

        
public CriteriaType CriteriaType
        {
            
get;
            
protected set;
        }

        
#endregion

        
static protected string ParameterNameFormat(string field)
        {
            
return field.Replace('.''_');
        }
    }

    
public class TrueCriteria : BaseCriteria
    {
        
public override string Expression
        {
            
get { return "(1=1)"; }
        }
    }

    
public class EqualParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp;
        
public EqualParameterCriteria(String field, Object value)
        {
            
this.CriteriaType = CriteriaType.Parameter;
            cp 
= new CriteriaParameter(ParameterNameFormat(field), value, field);
            parameters.Add(cp);
        }

        
public override string Expression
        {
            
get { return string.Format("{2}{0}={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix); }
        }
    }

    
public class EqualCriteria : BaseCriteria
    {
        
protected String field;

        
protected Object value;

        
public EqualCriteria(String field, Object value)
        {

            
this.field = field;

            
this.value = value;

        }

        
public override string Expression
        {
            
get
            {
                
if (value.GetType() == typeof(int||
                    value.GetType() 
== typeof(double||
                    value.GetType() 
== typeof(bool))
                    
return string.Format("{2}{0}={1}", field, value, FieldPrefix);
                
return string.Format("{2}{0}='{1}'", field, value, FieldPrefix);
            }
        }

    }

    
public class NotEqualParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp;
        
public NotEqualParameterCriteria(String field, Object value)
        {
            
this.CriteriaType = CriteriaType.Parameter;
            cp 
= new CriteriaParameter(ParameterNameFormat(field), value, field);
            parameters.Add(cp);
        }

        
public override string Expression
        {
            
get
            {
                
return string.Format("{2}{0}!={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix);
            }
        }
    }

    
public class NotEqualCriteria : BaseCriteria
    {
        
protected String field;

        
protected Object value;

        
public NotEqualCriteria(String field, Object value)
        {

            
this.field = field;

            
this.value = value;


        }
        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
if (value.GetType() == typeof(int||
                    value.GetType() 
== typeof(double||
                    value.GetType() 
== typeof(bool))
                    
return string.Format("{2}{0}!={1}", field, value, FieldPrefix);
                
return string.Format("{2}{0}!='{1}'", field, value, FieldPrefix);

            }
        }

        
#endregion
    }

    
public class GreaterThanParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp;
        
public GreaterThanParameterCriteria(String field, Object value)
        {
            
this.CriteriaType = CriteriaType.Parameter;
            cp 
= new CriteriaParameter(ParameterNameFormat(field), value, field);
            parameters.Add(cp);
        }

        
public override string Expression
        {
            
get
            {
                
return string.Format("{2}{0}>{3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix);
            }
        }
    }

    
public class GreaterThanCriteria : BaseCriteria
    {

        
protected String field;

        
protected Object value;

        
public GreaterThanCriteria(String field, Object value)
        {

            
this.field = field;

            
this.value = value;

        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
if (value.GetType() == typeof(int||
                    value.GetType() 
== typeof(double))
                    
return string.Format("{2}{0}>{1}", field, value, FieldPrefix);
                
return string.Format("{2}{0}>'{1}'", field, value, FieldPrefix);

            }
        }

        
#endregion
    }

    
public class GreaterEqualThanParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp;
        
public GreaterEqualThanParameterCriteria(String field, Object value)
        {
            
this.CriteriaType = CriteriaType.Parameter;
            cp 
= new CriteriaParameter(ParameterNameFormat(field), value, field);
            parameters.Add(cp);
        }

        
public override string Expression
        {
            
get
            {
                
return string.Format("{2}{0}>={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix);
            }
        }
    }

    
public class GreaterEqualThanCriteria : BaseCriteria
    {

        
protected String field;

        
protected Object value;

        
public GreaterEqualThanCriteria(String field, Object value)
        {

            
this.field = field;

            
this.value = value;

        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
if (value.GetType() == typeof(int||
                    value.GetType() 
== typeof(double))
                    
return string.Format("{2}{0}>={1}", field, value, FieldPrefix);
                
return string.Format("{2}{0}>='{1}'", field, value, FieldPrefix);
            }
        }

        
#endregion
    }

    
public class LessThanParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp;
        
public LessThanParameterCriteria(String field, Object value)
        {
            
this.CriteriaType = CriteriaType.Parameter;
            cp 
= new CriteriaParameter(ParameterNameFormat(field), value, field);
            parameters.Add(cp);
        }

        
public override string Expression
        {
            
get
            {
                
return string.Format("{2}{0}<{3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix);
            }
        }
    }

    
public class LessThanCriteria : BaseCriteria
    {

        
protected String field;

        
protected Object value;

        
public LessThanCriteria(String field, Object value)
        {

            
this.field = field;

            
this.value = value;

        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
if (value.GetType() == typeof(int||
                    value.GetType() 
== typeof(double))
                    
return string.Format("{2}{0}<{1}", field, value, FieldPrefix);
                
return string.Format("{2}{0}<'{1}'", field, value, FieldPrefix);
            }
        }

        
#endregion
    }

    
public class LessEqualThanParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp;
        
public LessEqualThanParameterCriteria(String field, Object value)
        {
            
this.CriteriaType = CriteriaType.Parameter;
            cp 
= new CriteriaParameter(ParameterNameFormat(field), value, field);
            parameters.Add(cp);
        }

        
public override string Expression
        {
            
get
            {
                
return string.Format("{2}{0}<={3}{1}", cp.Field, cp.Name, FieldPrefix, NamePrefix);
            }
        }
    }

    
public class LessEqualThanCriteria : BaseCriteria
    {

        
protected String field;

        
protected Object value;

        
public LessEqualThanCriteria(String field, Object value)
        {

            
this.field = field;

            
this.value = value;

        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
if (value.GetType() == typeof(int||
                    value.GetType() 
== typeof(double))
                    
return string.Format("{2}{0}<={1}", field, value, FieldPrefix);
                
return string.Format("{2}{0}<='{1}'", field, value, FieldPrefix);
            }
        }

        
#endregion
    }

    
public class LikeCriteria : BaseCriteria
    {
        
public enum LikeCriteriaType
        {
            NoneWildcard,
            LeftWildcard,
            RightWildcard,
            BothWildcard
        }

        LikeCriteriaType wildcard 
= LikeCriteriaType.NoneWildcard;

        
protected String field;

        
protected Object value;


        
public LikeCriteria(String field, Object value, LikeCriteriaType wildcard)
        {

            
this.field = field;

            
this.value = value;

            
this.wildcard = wildcard;
        }

        
public LikeCriteria(String field, Object value) : this(field, value, LikeCriteriaType.BothWildcard) { }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
switch (wildcard)
                {
                    
case LikeCriteriaType.NoneWildcard:
                        
return string.Format("{2}{0} like '{1}'", field, value, FieldPrefix);
                    
case LikeCriteriaType.LeftWildcard:
                        
return string.Format("{2}{0} like '%{1}'", field, value, FieldPrefix);
                    
case LikeCriteriaType.RightWildcard:
                        
return string.Format("{2}{0} like '{1}%'", field, value, FieldPrefix);
                    
case LikeCriteriaType.BothWildcard:
                        
return string.Format("{2}{0} like '%{1}%'", field, value, FieldPrefix);
                    
default:
                        
return string.Empty;
                }
            }
        }

        
#endregion
    }

    
public class BetweenCriteria : BaseCriteria
    {
        
string begin_expression;
        
string end_expression;
        
string field;


        
public BetweenCriteria(String field, string begin_expression, string end_expression)
        {
            
this.field = field;
            
this.begin_expression = begin_expression;
            
this.end_expression = end_expression;
        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get
            {
                
return string.Format("{3}{0} BETWEEN {1} AND {2}", field, begin_expression, end_expression, FieldPrefix);
            }
        }

        
#endregion

    }

    
public class BetweenParameterCriteria : BaseCriteria
    {
        CriteriaParameter cp1;
        CriteriaParameter cp2;

        
public BetweenParameterCriteria(string field, object begin_expression, object end_expression)
        {
            
string fieldPamaName1 = string.Format("{0}1", field);
            
string fieldPamaName2 = string.Format("{0}2", field);


            cp1 
= new CriteriaParameter(ParameterNameFormat(fieldPamaName1), begin_expression, field);
            parameters.Add(cp1);
            cp2 
= new CriteriaParameter(ParameterNameFormat(fieldPamaName2), end_expression, field);
            parameters.Add(cp2);
            
this.CriteriaType = CriteriaType.Parameter;

        }

        
public override string Expression
        {
            
get
            {
                
return string.Format("{3}{0} BETWEEN {4}{1} AND {4}{2}", cp1.Field, cp1.Name, cp2.Name, FieldPrefix, NamePrefix);
            }
        }
    }

    
public class NotCriteria : BaseCriteria
    {

        
protected ICriteria c1;

        
public NotCriteria(ICriteria c1)
        {

            
this.c1 = c1;
            
if (c1.CriteriaType == CriteriaType.Parameter)
            {
                parameters.AddRange(c1.Parameters);
                CriteriaType 
= CriteriaType.Parameter;
            }
        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get { return string.Format("NOT({0})"this.c1.Expression); }
        }

        
#endregion
    }

    
public class AndCriteria : BaseCriteria
    {

        
protected ICriteria c1, c2;

        
public AndCriteria(ICriteria c1, ICriteria c2)
        {
            
this.c1 = c1;
            
this.c2 = c2;
            CriteriaType 
= c1.CriteriaType | c2.CriteriaType;
            c1.UniqueCriteriaParameter(c2);
            
if (c1.CriteriaType == CriteriaType.Parameter)
                parameters.AddRange(c1.Parameters);
            
if (c2.CriteriaType == CriteriaType.Parameter)
                parameters.AddRange(c2.Parameters);
        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get { return string.Format("{0} AND {1}", c1.Expression, c2.Expression); }
        }

        
#endregion

    }

    
public class OrCriteria : BaseCriteria
    {

        
protected ICriteria c1, c2;

        
public OrCriteria(ICriteria c1, ICriteria c2)
        {
            
this.c1 = c1;
            
this.c2 = c2;
            CriteriaType 
= c1.CriteriaType | c2.CriteriaType;
            c1.UniqueCriteriaParameter(c2);
            
if (c1.CriteriaType == CriteriaType.Parameter)
                parameters.AddRange(c1.Parameters);
            
if (c2.CriteriaType == CriteriaType.Parameter)
                parameters.AddRange(c2.Parameters);
        }

        
#region ICriteria 成员

        
public override string Expression
        {
            
get { return string.Format("{0} OR {1}", c1.Expression, c2.Expression); }
        }

        
#endregion

    }

    
public static class CriteriaExtentsions
    {
        
static public void UniqueCriteriaParameter(this ICriteria c1, ICriteria c2)
        {
            
bool isBothParameter = (c1.CriteriaType & c2.CriteriaType) > 0;
            
if (isBothParameter)
            {
                
foreach (var p in c1.Parameters)
                {
                    var it 
= c2.Parameters.FirstOrDefault(x => x.Name == p.Name);
                    
if (it != null)
                    {
                        
int index = 1;
                        
string testName = it.Name + index.ToString();
                        
while (c2.Parameters.ToList().Exists(x => x.Name == testName) ||
                            c1.Parameters.ToList().Exists(x 
=> x.Name == testName))
                        {
                            
++index;
                            testName 
= it.Name + index.ToString();
                        }
                        it.Name 
= testName;
                    }
                }
            }
        }
    }
}
看到了吧,我们把所有可能的查询条件都给实现啦,以后无论遇到多么复杂的组合查询,我们都不怕啦!

OK,现在我们继续,我们在Repository文件夹下创建一个类BaseRepositoryBase.cs,这个类是要继承IRepository接口,实现里面的方法,这样,就把增删查改方法给抽象出来,以后的类只要继承BaseRepositoryBase.cs,就不用自己去实现啦。
本篇结束,请继续阅读 跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(四)Models(ORM、Repository模式、分页


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多