美文网首页
abp中建立Npoco仓储

abp中建立Npoco仓储

作者: 悦_547b | 来源:发表于2019-07-09 17:17 被阅读0次

    因为一直使用的Npoco,希望中以把Npoco作为abp的数据访问层,具体要如何实现呢?

    中间要用到注入,配置,模块等各种abp的知识,因为对abp的源码并不是特别熟悉,反复的看了很多文章,终于可以把逻辑搞明白了,在这里记录一下。

    参考dapper,首先是模块的定义,

    总体看一下

    ![image.png](https://img.haomeiwen.com/i1727627/ad4d44da0e4d936d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    >这里是模块的代码

    在模块中注册了模块的配置项,并且完成了模块和仓储的注册

    ```

    using Abp.Dependency;

    using Abp.Modules;

    using Abp.Npoco.Repository;

    using Abp.Orm;

    using Abp.Reflection.Extensions;

    namespace Abp.Npoco

    {

    [DependsOn(typeof(AbpKernelModule))]

        public class AbpNpocoModule : AbpModule

        {

            public override void PreInitialize()

            {

                IocManager.Register<AbpNpocoModuleConfig>();

                Configuration.UnitOfWork.IsTransactionScopeAvailable = false;

            }

            public override void Initialize()

            {

                IocManager.RegisterAssemblyByConvention(typeof(AbpNpocoModule).GetAssembly());

                IocManager.Register(typeof(INpocoRepository<>), typeof(NpocoRepositoryBase<>), DependencyLifeStyle.Transient);

                IocManager.Register(typeof(INpocoRepository<,>), typeof(NpocoRepositoryBase<,>), DependencyLifeStyle.Transient);

            }

        }

    }

    ```

    >然后是配置项的代码,

    这里配置项的代码是写了一个字典,用于存储数据库,本来是想,如果有多个数据库,可以在配置时写入,在仓储配置时,写一下自己用的是哪个数据库,但是又发现,可能在后面需要使用这个数据库,比如事务的处理,所以这里仅用于传入默认的数据库。

    ```

    using System;

    using System.Collections.Generic;

    using System.Text;

    using NPoco;

    namespace Abp.Npoco

    {

      public  class AbpNpocoModuleConfig

        {

            public static Dictionary<string, Database> DatabaseDic = new Dictionary<string, Database>();

            public void AddDb (string str,Database db)

            {

                DatabaseDic.Add(str, db);

            }

          }

    }

    ```

    >为方便完成配置,需要再写一个扩展类

    ```

    using Abp.Configuration.Startup;

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace Abp.Npoco

    {

        public static class AbpNpocoModuleConfigurationiExtensions

        {

            public static AbpNpocoModuleConfig AbpNpocoModule(this IModuleConfigurations configuration)

            {

                return configuration.AbpConfiguration.Get<AbpNpocoModuleConfig>();

            }

        }

    }

    ```

    >到这里,基本配置就完成了,下面是仓储的代码部分

    >首先定义接口INpocoRepository

    ```

    using Abp.Domain.Repositories;

    using System;

    using System.Collections.Generic;

    using System.Text;

    using JetBrains.Annotations;

    using Abp.Domain.Entities;

    using NPoco;

    namespace Abp.Npoco.Repository

    {

        /// <summary>

        ///    Dapper repository abstraction interface.

        /// </summary>

        /// <typeparam name="TEntity">The type of the entity.</typeparam>

        /// <typeparam name="TPrimaryKey">The type of the primary key.</typeparam>

        /// <seealso cref="INpocoRepository{TEntity,TPrimaryKey}" />

        public interface INpocoRepository<TEntity, TPrimaryKey> : IRepository where TEntity : class, IEntity<TPrimaryKey>

        {

            void SetDatabase(Database db);

            /// <summary>

            ///    Gets the specified identifier.

            /// </summary>

            /// <param name="id">The identifier.</param>

            /// <returns></returns>

            [NotNull]

            TEntity Single([NotNull] TPrimaryKey id);

            bool Exists(TPrimaryKey id);

            TEntity First(string sql, params object[] args);

            TEntity First(string sql);

            TEntity FirstOrDefault(string sql, params object[] args);

            TEntity FirstOrDefault(string sql);

            TEntity SingleById(TPrimaryKey id);

            object Insert(TEntity entity);

            int InsertBatch(IEnumerable<TEntity> entitys);

            int Update(TEntity entity);

            // public abstract int UpdateBatch(IEnumerable<TEntity> entitys);

            int Delete(TEntity entity);

            void Save(TEntity entity);

            List<TEntity> Fetch();

            List<TEntity> Fetch(string sql);

            List<TEntity> Fetch(string sql, params object[] args);

            Page<TEntity> Page(long page, int itemsPerPage, string sql);

            Page<TEntity> Page(long page, int itemsPerPage, string sql, params object[] args);

            IEnumerable<TEntity> Query(string sql, params object[] args);

            IEnumerable<TEntity> Query(string sql);

            int Execute(string sql, params object[] args);

            int Execute(string sql);

        }

    }

    ```

    >定义默认的主键是整型

    ```

    using Abp.Domain.Entities;

    using Abp.Domain.Repositories;

    namespace Abp.Npoco.Repository

    {

        public interface INpocoRepository<TEntity> : INpocoRepository<TEntity, int> where TEntity : class, IEntity<int>

        {

        }

    }

    ```

    >定义抽象类AbpNpocoRepositoryBase

    ```

    using System;

    using System.Collections.Generic;

    using System.Linq.Expressions;

    using System.Threading.Tasks;

    using Abp.Dependency;

    using Abp.Domain.Entities;

    using Abp.Domain.Uow;

    using Abp.MultiTenancy;

    using Abp.Reflection.Extensions;

    using NPoco;

    namespace Abp.Npoco.Repository

    {

        /// <summary>

        ///    Base class to implement <see cref="IDapperRepository{TEntity,TPrimaryKey}" />.

        ///    It implements some methods in most simple way.

        /// </summary>

        /// <typeparam name="TEntity">The type of the entity.</typeparam>

        /// <typeparam name="TPrimaryKey">The type of the primary key.</typeparam>

        /// <seealso cref="IDapperRepository{TEntity,TPrimaryKey}" />

        public abstract class AbpNpocoRepositoryBase<TEntity, TPrimaryKey> : INpocoRepository<TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey>

        {

            static AbpNpocoRepositoryBase()

            {

                var attr = typeof(TEntity).GetSingleAttributeOfTypeOrBaseTypesOrNull<MultiTenancySideAttribute>();

            }

            public abstract void  SetDatabase(Database db);

            public abstract bool Exists(TPrimaryKey id);

            public abstract TEntity First(string sql, params object[] args);

            public abstract TEntity First(string sql);

            public abstract TEntity FirstOrDefault(string sql, params object[] args);

            public abstract TEntity FirstOrDefault(string sql);

            public abstract TEntity Single(TPrimaryKey id);

            public abstract TEntity SingleById(TPrimaryKey id);

            public abstract object Insert(TEntity entity);

            public abstract int InsertBatch(IEnumerable<TEntity> entitys);

            public abstract int Update(TEntity entity);

            // public abstract int UpdateBatch(IEnumerable<TEntity> entitys);

            public abstract int Delete(TEntity entity);

            public abstract void Save(TEntity entity);

            public abstract List<TEntity> Fetch();

            public abstract List<TEntity> Fetch(string sql);

            public abstract List<TEntity> Fetch(string sql, params object[] args);

            public abstract Page<TEntity> Page(long page, int itemsPerPage, string sql);

            public abstract Page<TEntity> Page(long page, int itemsPerPage, string sql, params object[] args);

            public abstract IEnumerable<TEntity> Query(string sql, params object[] args);

            public abstract IEnumerable<TEntity> Query(string sql);

            public abstract int Execute(string sql, params object[] args);

            public abstract int Execute(string sql);

            public virtual Task<TEntity> SingleAsync(TPrimaryKey id)

            {

                return Task.FromResult(Single(id));

            }

            public virtual Task<TEntity> FirstAsync(string sql, params object[] args)

            {

                return Task.FromResult(First(sql, args));

            }

            public virtual Task<TEntity> FirstAsync(string sql)

            {

                return Task.FromResult(First(sql));

            }

            public virtual Task<TEntity> FirstOrDefaultAsync(string sql, params object[] args)

            {

                return Task.FromResult(FirstOrDefault(sql, args));

            }

            public virtual Task<TEntity> FirstOrDefaultAsync(string sql)

            {

                return Task.FromResult(FirstOrDefault(sql));

            }

        }

    }

    ```

    > 实现功能NpocoRepositoryBase

    ```

    using System;

    using System.Collections.Generic;

    using System.Data.Common;

    using System.Linq;

    using System.Linq.Expressions;

    using System.Threading.Tasks;

    using System.Data.SqlClient;

    using NPoco.FluentMappings;

    using Abp.Data;

    using Abp.Domain.Entities;

    using Abp.Domain.Uow;

    using Abp.Events.Bus.Entities;

    using NPoco;

    using Abp.Configuration;

    namespace Abp.Npoco.Repository

    {

        public class NpocoRepositoryBase<TEntity, TPrimaryKey> : AbpNpocoRepositoryBase<TEntity, TPrimaryKey>

                where TEntity : class, IEntity<TPrimaryKey>

        {

            public NpocoRepositoryBase()

            {

              Database db = null;

              AbpNpocoModuleConfig.DatabaseDic.TryGetValue("Default",out db);

                Db = db;

            }

            public Database Db { get; set; }

            public override void SetDatabase(Database db)

            {

                Db = db;

            }

            /// <summary>

            ///    Gets the active transaction. If Dapper is active then <see cref="IUnitOfWork" /> should be started before

            ///    and there must be an active transaction.

            /// </summary>

            /// <value>

            ///    The active transaction.

            /// </value>

            public override bool Exists(TPrimaryKey id  )

            {

                return Db.Exists<TEntity>(id);

            }

            public override TEntity First(string sql, params object[] args)

            {

                return Db.First<TEntity>(sql, args);

            }

            public override TEntity First(string sql)

            {

                return Db.First<TEntity>(sql);

            }

            public override TEntity Single(TPrimaryKey id)

            {

                return Db.SingleById<TEntity>(id);

            }

            public override TEntity SingleById(TPrimaryKey id)

            {

                return Db.SingleById<TEntity>(id);

            }

            public override TEntity FirstOrDefault(string sql, params object[] args)

            {

                return Db.FirstOrDefault<TEntity>(sql, args);

            }

            public override TEntity FirstOrDefault(string sql)

            {

                return Db.FirstOrDefault<TEntity>(sql);

            }

            public override object Insert(TEntity entity)

            {

                return Db.Insert<TEntity>(entity);

            }

            public override int InsertBatch(IEnumerable<TEntity> entitys)

            {

                return Db.InsertBatch<TEntity>(entitys);

            }

            public override int Update(TEntity entity)

            {

                return Db.Update(entity);

            }

            public override int Delete(TEntity entity)

            {

                return Db.Delete(entity);

            }

            public override void Save(TEntity entity)

            {

                Db.Save(entity);

            }

            public override List<TEntity> Fetch()

            {

                return Db.Fetch<TEntity>();

            }

            public override List<TEntity> Fetch(string sql){

              return  Db.Fetch<TEntity>(sql);

            }

            public override List<TEntity> Fetch( string sql, params object[] args)

            {

                return  Db.Fetch<TEntity>(sql,args);

            }

            public override Page<TEntity> Page(long page,int itemsPerPage,string sql)

            {

                return Db.Page<TEntity>(page, itemsPerPage, sql);

            }

            public override Page<TEntity> Page(long page, int itemsPerPage, string sql,params object[] args)

            {

                return Db.Page<TEntity>(page, itemsPerPage, sql, args);

            }

            public override IEnumerable<TEntity> Query(string sql, params object[] args)

            {

              return Db.Query<TEntity>(sql,args);

            }

            public override IEnumerable<TEntity> Query(string sql)

            {

                return Db.Query<TEntity>(sql);

            }

            public override int Execute(string sql, params object[] args)

            {

                return Db.Execute(sql, args);

            }

            public override int Execute(string sql)

            {

                return Db.Execute(sql);

            }

        }

    }

    ```

    >实现功能默认为整型的主键

    ```

    using System;

    using System.Collections.Generic;

    using System.Data.Common;

    using System.Linq;

    using System.Linq.Expressions;

    using System.Threading.Tasks;

    using System.Data.SqlClient;

    using NPoco.FluentMappings;

    using Abp.Data;

    using Abp.Domain.Entities;

    using Abp.Domain.Uow;

    using Abp.Events.Bus.Entities;

    using NPoco;

    using Abp.Configuration;

    namespace Abp.Npoco.Repository

    {

        public class NpocoRepositoryBase<TEntity> : NpocoRepositoryBase<TEntity, int>, INpocoRepository<TEntity>

        where TEntity : class, IEntity<int>

        { }

    }

    ```

    >到这里,代码就完成了,后面是具体的引用了

    一般情况下,引用时,这个可以放在一个单独的仓储层,也可以直接在应用层直接声明使用根据具体情况来看要怎么处理。

    感觉比较简单的方式,是直接在应用层来用比较好,如果是要操作多个表或者库的,就在应用层处理,或者如果有必需,做一个领域层也可以。

    >第一步,在模块中添加依赖,并配置数据库

    ![image.png](https://img.haomeiwen.com/i1727627/a606836cfb461424.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    添加数据库配置

    ```

                var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());

                string constr = configuration.GetConnectionString(DemoConsts.ConnectionStringName);

                Database db = new Database(constr, DatabaseType.MySQL, MySqlClientFactory.Instance);

                Configuration.Modules.AbpNpocoModule().AddDb("Default",db);

    ```

    >在应用层声明和使用仓储

    ```

      private readonly INpocoRepository<Person> personRepository;

            PersonRepository per;

            //  private readonly INpocoRepository<Person>  ptory;

            public StaffAppService(INpocoRepository<Person> _personRepository, PersonRepository _per)

            {

              //  _personDapperRepository = personDapperRepository;

                personRepository = _personRepository;

              // personRepository.SetDatabase(DataManager.GetDb());

                per = _per;

            }

    ```

    也可以单独的写仓储层,如下所示

    ![image.png](https://img.haomeiwen.com/i1727627/aaa3f0df77e2a1b8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    ```

    namespace Demo.Repositorys

    {

        public class  PersonRepository: NpocoRepositoryBase<Person>,IPersonRepository

        {

        public  PersonRepository()

            {

                Db = DataManager.GetDb();

            }

    ```

    相关文章

      网友评论

          本文标题:abp中建立Npoco仓储

          本文链接:https://www.haomeiwen.com/subject/kilfkctx.html