统一的仓储接口

  • Post author:
  • Post category:其他


目前,各种数据访问组件多如牦牛,提供接口各不相同,虽然大多都支持不同数据存储,但是还是存在一些问题,

有的团队成员喜欢用EF,有的喜欢用NHibernate,口味难调。于是我希望能有一组标准的接口,这样可以统一

代码的,也可以满足各成员的喜好。

目前来说,linq的出现,大大简化了代码的冗余和复杂性,

所以这组接口是建立在linq的基础上的,支持linq的数据访问组件目前有EF,NHibernate,IQtoolkit,Dblinq等。

这里面有两个重要的对象,Context(上下文对象)和Repository(仓储对象)。

我希望调用者只需要尽量少的对象和尽量少的方法。使得接口清晰简单。

首先上下文对象Context,它能够获得仓储对象并完成事务提交即可。


public


interface

IObjectContext:IDisposable

{




string

Name {

get

;

set

; }



IRepository GetRepository<T>();




bool

SaveChanges();

}

接着仓储对象Repository,它则可以对T类型的数据进行CRUD,并且还能像IQueryable那样支持很多操作。


public




interface


IRepository<T> : IQueryable<T>


where


T :


class


,IEntity,


new


()

{

T CreateModel();


bool

New(T entity);


bool

Update(T entity);


bool

Delete(T t);


bool

VirtualDelete(T t);

Guid NewGuid();


decimal

NewId();

}

仓储对不同数据访问组件有些共同的东西,加之实现IQueryable,所以增加抽象类AbstractRepository


public


abstract


class

AbstractRepository<T> : IRepository<T>

where

T :

class

,IEntity,

new

()

{


public

IObjectContext Context {

get

;

private


set

; }


public

AbstractRepository(IObjectContext context)

{

Context = context;

}


protected


abstract

IQueryable<T> GetQueryable();


public


abstract


bool

New(T entity);


public


abstract


bool

Update(T entity);


public


abstract


bool

Delete(T t);


public


abstract


bool

VirtualDelete(T t);


public


virtual

T CreateModel()

{


return


new

T();

}


public


virtual

Guid NewGuid() {

return

Guid.NewGuid(); }


public


virtual


decimal

NewId() {

return


decimal

.Zero; }


public

IEnumerator<T> GetEnumerator()

{


return

GetQueryable().GetEnumerator();

}

IEnumerator IEnumerable.GetEnumerator()

{


return

GetQueryable().GetEnumerator();

}


public

Type ElementType

{


get

{

return

GetQueryable().ElementType; }

}


public

Expression Expression

{


get

{

return

GetQueryable().Expression; }

}


public

IQueryProvider Provider

{


get

{

return

GetQueryable().Provider; }

}


}

主要的就需要这三个接口

代码写起来就是这样子


using


(


var


context = ContextFactory.Create(contextName


))

{


var

r = context.GetRepository<T>();


var

instance = r.CreateModel();

instance.Copy(tdto);

instance.Validate(context);

r.New(instance);

context.SaveChanges();


return

instance;

}

这些重复性的代码,直接扩展到接口上,封装起来,外面只需继承此接口。

下面是EF的仓储实现


public




class


EFRepository<T> : AbstractRepository<T>


where


T :


class


,IEntity,


new


()

{

ObjectContext _context =

null

;


public

EFRepository(IObjectContext context) :

base

(context) {

_context =

base

.Context

as

ObjectContext;


if

(_context ==

null

) {

throw


new

Exception(




EFRepository中上下文对象不是System.Data.Objects.ObjectContext对象。




); }

}


public


override


bool

New(T entity)

{

GetObjectSet().AddObject(entity);


return


true

;

}


public


override


bool

Update(T entity)

{


return


true

;

}


public


override


bool

Delete(T t)

{

GetObjectSet().DeleteObject(t);


return


true

;

}


public


override


bool

VirtualDelete(T t)

{


return


true

;

}


protected


override

IQueryable<T> GetQueryable()

{


return

GetObjectSet();

}

ObjectSet<T> GetObjectSet()

{


return

_context.CreateObjectSet<T>();

}

}

其它的仓储实现也比较简单,附上源码


Repository.rar

转载于:https://www.cnblogs.com/bmrxntfj/archive/2011/11/09/2242277.html