zoukankan      html  css  js  c++  java
  • 统一的仓储接口

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

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

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

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

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

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

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

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

    public interface IObjectContext:IDisposable
    {
         string Name { getset; }
        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 { getprivate 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

  • 相关阅读:
    Chrome 请求过滤扩展实现
    【译】Chrome 扩展 : 入门
    【译】Chrome 扩展 : 扩展是什么?
    【译】Chrome 扩展 : 欢迎
    事务处理
    nrm ls报错解决办法
    Typescript学习总结
    常用插件收藏
    css 设置滚动条样式
    vscode 常用插件
  • 原文地址:https://www.cnblogs.com/bmrxntfj/p/2242277.html
Copyright © 2011-2022 走看看