目前,各种数据访问组件多如牦牛,提供接口各不相同,虽然大多都支持不同数据存储,但是还是存在一些问题,
有的团队成员喜欢用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>();
}
}
其它的仓储实现也比较简单,附上源码
转载于:https://www.cnblogs.com/bmrxntfj/archive/2011/11/09/2242277.html