当前位置: 移动技术网 > IT编程>开发语言>.net > [开源]Entity Framework 6 Repository 一种实现方式

[开源]Entity Framework 6 Repository 一种实现方式

2019年04月10日  | 移动技术网IT编程  | 我要评论

张家界索道断裂,游客吃面获白吃证,杨大暑

  1. 在使用entity framework这种orm框架得时候,一般结合repository仓储形式来处理业务逻辑;虽然这种模式带来很多好处,但是也会引发一些争议,在此抛开不谈,小弟结合项目经验来实现一下,欢迎大佬拍砖;
  2. 后续会带来dapper 基于repository实现,代码一些实现会兼容dapper,所以做了一些比较丑陋得写法;但是我得想法是通过一些ioc可以在entity framework和dapper两者之间进行切换;
  3. 您可以通过nuget:install-package masterchief.dotnet.core.ef 安装使用;
  4. 您可以通过github:masterchief 查看具体源码以及单元测试
  5. 欢迎pr,欢迎star;

插播一条求职

  1. 小弟拥有多年c#开发经验,从事过路灯,消防平台物联网平台开发,坐标上海;
  2. 如果贵司在招聘,烦请大佬考虑下,联系邮箱:meetyan@outlook.com

标准仓储

/// <summary>
/// 标准仓储接口
/// </summary>
public interface irepository
{
    #region methods
 
    /// <summary>
    /// 删除记录
    /// </summary>
    /// <returns>操作是否成功</returns>
    /// <param name="entity">需要操作的实体类.</param>
    bool delete<t>(t entity) where t : modelbase;
 
    /// <summary>
    /// 条件判断是否存在
    /// </summary>
    /// <returns>是否存在</returns>
    /// <param name="predicate">判断条件委托</param>
    bool exist<t>(expression<func<t, bool>> predicate = null) where t : modelbase;
 
    /// <summary>
    /// 根据id获取记录
    /// </summary>
    /// <returns>记录</returns>
    /// <param name="id">id.</param>
    t getbykeyid<t>(object id) where t : modelbase;
 
    /// <summary>
    /// 条件获取记录集合
    /// </summary>
    /// <returns>集合</returns>
    /// <param name="predicate">筛选条件.</param>
    list<t> getlist<t>(expression<func<t, bool>> predicate = null) where t : modelbase;
 
    /// <summary>
    /// 条件获取记录第一条或者默认
    /// </summary>
    /// <returns>记录</returns>
    /// <param name="predicate">筛选条件.</param>
    t getfirstordefault<t>(expression<func<t, bool>> predicate = null) where t : modelbase;
 
    /// <summary>
    /// 创建一条记录
    /// </summary>
    /// <returns>操作是否成功.</returns>
    /// <param name="entity">实体类记录.</param>
    bool create<t>(t entity) where t : modelbase;
 
    /// <summary>
    /// 条件查询
    /// </summary>
    /// <returns>iqueryable</returns>
    /// <param name="predicate">筛选条件.</param>
    iqueryable<t> query<t>(expression<func<t, bool>> predicate = null) where t : modelbase;
 
    /// <summary>
    /// 根据记录
    /// </summary>
    /// <returns>操作是否成功.</returns>
    /// <param name="entity">实体类记录.</param>
    bool update<t>(t entity) where t : modelbase;
 
    #endregion methods
}

数据访问上下文接口

public interface idbcontext : idisposable, irepository, iunitofwork
{
    /// <summary>
    ///     执行sql 脚本查询
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">参数</param>
    /// <returns>集合</returns>
    ienumerable<t> sqlquery<t>(string sql, idbdataparameter[] parameters);
}

数据访问上下文工厂

public interface idatabasecontextfactory
{
    /// <summary>
    ///     create this instance.
    /// </summary>
    /// <returns>the create.</returns>
    idbcontext create();
}

基于ef的dbcontext

public abstract class efdbcontextbase : dbcontext, idbcontext
{
    #region constructors
 
    /// <summary>
    ///     构造函数
    /// </summary>
    /// <param name="dbconnection">dbconnection</param>
    protected efdbcontextbase(dbconnection dbconnection)
        : base(dbconnection, true)
    {
        configuration.lazyloadingenabled = false; //将不会查询到从表的数据,只会执行一次查询,可以使用 inculde 进行手动加载;
        configuration.proxycreationenabled = false;
        configuration.autodetectchangesenabled = false;
    }
 
    #endregion constructors
 
    #region fields
 
    /// <summary>
    ///     获取 是否开启事务提交
    /// </summary>
    public virtual bool transactionenabled => database.currenttransaction != null;
 
    #endregion fields
 
    #region methods
 
    /// <summary>
    ///     显式开启数据上下文事务
    /// </summary>
    /// <param name="isolationlevel">指定连接的事务锁定行为</param>
    public void begintransaction(isolationlevel isolationlevel = isolationlevel.unspecified)
    {
        if (!transactionenabled) database.begintransaction(isolationlevel);
    }
 
    /// <summary>
    ///     提交当前上下文的事务更改
    /// </summary>
    /// <exception cref="dataaccessexception">提交数据更新时发生异常:" + msg</exception>
    public void commit()
    {
        if (transactionenabled)
            try
            {
                database.currenttransaction.commit();
            }
            catch (dbupdateexception ex)
            {
                if (ex.innerexception?.innerexception is sqlexception sqlex)
                {
                    var msg = databasehelper.getsqlexceptionmessage(sqlex.number);
                    throw new dataaccessexception("提交数据更新时发生异常:" + msg, sqlex);
                }
 
                throw;
            }
    }
 
    /// <summary>
    ///     创建记录
    /// </summary>
    /// <returns>操作是否成功</returns>
    /// <param name="entity">需要操作的实体类.</param>
    public bool create<t>(t entity)
        where t : modelbase
    {
        validateoperator.begin().notnull(entity, "需要创建数据记录");
        bool result;
        try
        {
            entry(entity).state = entitystate.added;
            result = savechanges() > 0;
        }
        catch (dbentityvalidationexception dbex)
        {
            throw new exception(dbex.getfullerrortext(), dbex);
        }
 
        return result;
    }
 
    /// <summary>
    ///     创建记录集合
    /// </summary>
    /// <returns>操作是否成功.</returns>
    /// <param name="entities">实体类集合.</param>
    public bool create<t>(ienumerable<t> entities)
        where t : modelbase
    {
        validateoperator.begin().notnull(entities, "需要创建数据集合");
        bool result;
        try
        {
            foreach (var entity in entities) entry(entity).state = entitystate.added;
 
            result = savechanges() > 0;
        }
        catch (dbentityvalidationexception dbex)
        {
            throw new exception(dbex.getfullerrortext(), dbex);
        }
 
        return result;
    }
 
    /// <summary>
    ///     删除记录
    /// </summary>
    /// <returns>操作是否成功</returns>
    /// <param name="entity">需要操作的实体类.</param>
    public bool delete<t>(t entity)
        where t : modelbase
    {
        validateoperator.begin().notnull(entity, "需要删除的数据记录");
        bool result;
        try
        {
            entry(entity).state = entitystate.deleted;
            result = savechanges() > 0;
        }
        catch (dbentityvalidationexception dbex)
        {
            throw new exception(dbex.getfullerrortext(), dbex);
        }
 
        return result;
    }
 
    /// <summary>
    ///     条件判断是否存在
    /// </summary>
    /// <returns>是否存在</returns>
    /// <param name="predicate">判断条件委托</param>
    public bool exist<t>(expression<func<t, bool>> predicate = null)
        where t : modelbase
    {
        return predicate == null ? set<t>().any() : set<t>().any(predicate);
    }
 
    /// <summary>
    ///     根据id获取记录
    /// </summary>
    /// <returns>记录</returns>
    /// <param name="id">id.</param>
    public t getbykeyid<t>(object id)
        where t : modelbase
    {
        validateoperator.begin().notnull(id, "id");
        return set<t>().find(id);
    }
 
    /// <summary>
    ///     条件获取记录集合
    /// </summary>
    /// <returns>集合</returns>
    /// <param name="predicate">筛选条件.</param>
    public list<t> getlist<t>(expression<func<t, bool>> predicate = null)
        where t : modelbase
    {
        iqueryable<t> query = set<t>();
 
        if (predicate != null) query = query.where(predicate);
 
        return query.tolist();
    }
 
    /// <summary>
    ///     条件获取记录第一条或者默认
    /// </summary>
    /// <returns>记录</returns>
    /// <param name="predicate">筛选条件.</param>
    public t getfirstordefault<t>(expression<func<t, bool>> predicate = null)
        where t : modelbase
    {
        iqueryable<t> query = set<t>();
 
        if (predicate != null)
            return query.firstordefault(predicate);
        return query.firstordefault();
    }
 
    /// <summary>
    ///     条件查询
    /// </summary>
    /// <returns>iqueryable</returns>
    /// <param name="predicate">筛选条件.</param>
    public iqueryable<t> query<t>(expression<func<t, bool>> predicate = null)
        where t : modelbase
    {
        iqueryable<t> query = set<t>();
 
        if (predicate != null) query = query.where(predicate);
 
        return query;
    }
 
    /// <summary>
    ///     显式回滚事务,仅在显式开启事务后有用
    /// </summary>
    public void rollback()
    {
        if (transactionenabled) database.currenttransaction.rollback();
    }
 
    /// <summary>
    ///     执行sql 脚本查询
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">参数</param>
    /// <returns>集合</returns>
    public ienumerable<t> sqlquery<t>(string sql, idbdataparameter[] parameters)
    {
        validateoperator.begin()
            .notnullorempty(sql, "sql语句");
        // resharper disable once covariantarrayconversion
        return database.sqlquery<t>(sql, parameters);
    }
 
    /// <summary>
    ///     根据记录
    /// </summary>
    /// <returns>操作是否成功.</returns>
    /// <param name="entity">实体类记录.</param>
    public bool update<t>(t entity)
        where t : modelbase
    {
        validateoperator.begin().notnull(entity, "需要更新的数据记录");
        bool result;
        try
        {
            var set = set<t>();
            set.attach(entity);
            entry(entity).state = entitystate.modified;
            result = savechanges() > 0;
        }
        catch (dbentityvalidationexception dbex)
        {
            throw new exception(dbex.getfullerrortext(), dbex);
        }
 
        return result;
    }
 
    #endregion methods
}

单元测试

    [testclass()]
    public class sampleservicetests
    {
        private ikernel _kernel;
        private isampleservice _sampleservice;
        private readonly guid _testid = "2f6d3c43-c2c7-4398-ad2b-ed5e82d79999".toguidordefault(guid.empty);
        private const string testname = "efsample";
 
        [testinitialize]
        public void setup()
        {
            _kernel = new standardkernel(new servicemodule());
            assert.isnotnull(_kernel);
 
            _sampleservice = _kernel.get<isampleservice>();
            //if (!_sampleservice.exist(ent => ent.id == _testid))
            //{
            //    _sampleservice.create(new efsample() { username = _testname, id = _testid });
            //}
        }
 
        /// <summary>
        /// 创建测试
        /// </summary>
        [testmethod()]
        public void createtest()
        {
            bool actual = _sampleservice.create(new efsample() { username = "ef" + datetime.now.tostring("mmddhhmmss") });
            assert.istrue(actual);
 
            actual = _sampleservice.create(new efsample() { username = "ef" + datetime.now.tostring("mmddhhmmss") });
            assert.istrue(actual);
 
            actual = _sampleservice.create(new efsample() { username = "ef" + datetime.now.tostring("mmddhhmmss") });
            assert.istrue(actual);
 
            actual = _sampleservice.create(new efsample() { username = "ef" + datetime.now.tostring("mmddhhmmss") });
            assert.istrue(actual);
 
            actual = _sampleservice.create(new efsample() { username = "ef" + datetime.now.tostring("mmddhhmmss") });
            assert.istrue(actual);
        }
 
        [testmethod()]
        public void getfirstordefaulttest()
        {
            efsample actual = _sampleservice.getfirstordefault(ent => ent.id == _testid);
            assert.isnotnull(actual);
        }
 
        [testmethod()]
        public void getbykeyidtest()
        {
            efsample actual = _sampleservice.getbykeyid(_testid);
            assert.isnotnull(actual);
        }
 
        [testmethod()]
        public void getlisttest()
        {
            // resharper disable once redundantboolcompare
            list<efsample> actual = _sampleservice.getlist(ent => ent.available == true);
            assert.isnotnull(actual);
            collectionassert.allitemsarenotnull(actual);
        }
 
        [testmethod()]
        public void updatetest()
        {
            efsample sample = new efsample
            {
                id = _testid,
                modifytime = datetime.now,
                username = "modify"
            };
            bool actual = _sampleservice.update(sample);
            assert.isnotnull(actual);
        }
 
        [testmethod()]
        public void transactionsuccesstest()
        {
            efsample sample = new efsample
            {
                username = "transactionsuccess1"
            };
 
            efsample sample2 = new efsample
            {
                username = "transactionsuccess2"
            };
            bool actual = _sampleservice.createwithtransaction(sample, sample2);
            assert.istrue(actual);
        }
 
        [testmethod()]
        public void transactionfailtest()
        {
            efsample sample3 = new efsample
            {
                username = "transactionsuccess3"
            };
 
            efsample sample4 = new efsample
            {
                username = null
            };
            bool actual = _sampleservice.createwithtransaction(sample3, sample4);
            assert.isfalse(actual);
        }
 
        [testmethod()]
        public void existtest()
        {
            bool actual = _sampleservice.exist(ent => ent.id == _testid);
            assert.istrue(actual);
 
            actual = _sampleservice.exist(ent => ent.username == testname);
            assert.istrue(actual);
 
            datetime createtime = datetime.now.adddays(-1);
            actual = _sampleservice.exist(ent => ent.createtime >= createtime);
            assert.istrue(actual);
 
            actual = _sampleservice.exist(ent => ent.createtime <= datetime.now);
            assert.istrue(actual);
 
            // resharper disable once redundantboolcompare
            actual = _sampleservice.exist(ent => ent.available == true);
            assert.istrue(actual);
 
            actual = _sampleservice.exist(ent => ent.available != true);
            assert.isfalse(actual);
        }
 
        [testmethod()]
        public void sqlquerytest()
        {
            string sql = @"select * from [dbo].[efsample]
where createtime>=@createtime
and available=@available
order by createtime desc";
            dbparameter[] parameter = {
                    new sqlparameter(){ parametername="@createtime", value=datetime.now.adddays(-1) },
                    new sqlparameter(){ parametername="@available", value=true }
                };
            list<efsample> actual = _sampleservice.sqlquery(sql, parameter);
            assert.isnotnull(actual);
            collectionassert.allitemsarenotnull(actual);
        }
 
        /// <summary>
        /// 多线程测试
        /// </summary>
        [testmethod()]
        public void createtestthreadtest()
        {
            task[] tasks = {
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                                task.factory.startnew(() => createtest()),
                            };
            task.waitall(tasks);
        }
    }

结语

  1. 通过上述代码,可以在项目中很方面使用entity framework;
  2. 并且很轻松实现curd以及事务处理,从而开发中关注业务即可;
  3. 小弟不才,大佬轻拍;

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网