abp中建立Npoco仓储

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

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

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

总体看一下

![image.png](https://upload-images.jianshu.io/upload_images/1727627-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();

            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 DatabaseDic = new Dictionary();


        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();

        }

    }

}

```

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

>首先定义接口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

{

    ///

    ///    Dapper repository abstraction interface.

    ///

    /// The type of the entity.

    /// The type of the primary key.

    ///

    public interface INpocoRepository : IRepository where TEntity : class, IEntity

    {

        void SetDatabase(Database db);


        ///

        ///    Gets the specified identifier.

        ///

        /// The identifier.

        ///

        [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 entitys);

        int Update(TEntity entity);

        // public abstract int UpdateBatch(IEnumerable entitys);

        int Delete(TEntity entity);

        void Save(TEntity entity);

        List Fetch();

        List Fetch(string sql);

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

        Page Page(long page, int itemsPerPage, string sql);

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

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

        IEnumerable 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 : INpocoRepository where TEntity : class, IEntity

    {

    }

}

```

>定义抽象类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

{


    ///

    ///    Base class to implement .

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

    ///

    /// The type of the entity.

    /// The type of the primary key.

    ///

    public abstract class AbpNpocoRepositoryBase : INpocoRepository where TEntity : class, IEntity

    {


        static AbpNpocoRepositoryBase()

        {

            var attr = typeof(TEntity).GetSingleAttributeOfTypeOrBaseTypesOrNull();


        }

        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 entitys);

        public abstract int Update(TEntity entity);

        // public abstract int UpdateBatch(IEnumerable entitys);

        public abstract int Delete(TEntity entity);

        public abstract void Save(TEntity entity);

        public abstract List Fetch();

        public abstract List Fetch(string sql);

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

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

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

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

        public abstract IEnumerable Query(string sql);

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

        public abstract int Execute(string sql);

        public virtual Task SingleAsync(TPrimaryKey id)

        {

            return Task.FromResult(Single(id));

        }

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

        {

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

        }

        public virtual Task FirstAsync(string sql)

        {

            return Task.FromResult(First(sql));

        }

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

        {

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

        }

        public virtual Task 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 : AbpNpocoRepositoryBase

            where TEntity : class, IEntity

    {


        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;

        }

        ///

        ///    Gets the active transaction. If Dapper is active then should be started before

        ///    and there must be an active transaction.

        ///

        ///

        ///    The active transaction.

        ///

        public override bool Exists(TPrimaryKey id  )

        {

            return Db.Exists(id);

        }

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

        {


            return Db.First(sql, args);

        }

        public override TEntity First(string sql)

        {

            return Db.First(sql);

        }

        public override TEntity Single(TPrimaryKey id)

        {

            return Db.SingleById(id);

        }

        public override TEntity SingleById(TPrimaryKey id)

        {

            return Db.SingleById(id);

        }

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

        {

            return Db.FirstOrDefault(sql, args);

        }

        public override TEntity FirstOrDefault(string sql)

        {

            return Db.FirstOrDefault(sql);

        }

        public override object Insert(TEntity entity)

        {

            return Db.Insert(entity);

        }

        public override int InsertBatch(IEnumerable entitys)

        {

            return Db.InsertBatch(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 Fetch()

        {

            return Db.Fetch();

        }

        public override List Fetch(string sql){

          return  Db.Fetch(sql);


        }

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

        {


            return  Db.Fetch(sql,args);

        }

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

        {

            return Db.Page(page, itemsPerPage, sql);

        }

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

        {

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


        }

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

        {


          return Db.Query(sql,args);

        }

        public override IEnumerable Query(string sql)

        {

            return Db.Query(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 : NpocoRepositoryBase, INpocoRepository

    where TEntity : class, IEntity

    { }

}

```

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

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

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

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

![image.png](https://upload-images.jianshu.io/upload_images/1727627-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 personRepository;

        PersonRepository per;

        //  private readonly INpocoRepository  ptory;

        public StaffAppService(INpocoRepository _personRepository, PersonRepository _per)

        {

          //  _personDapperRepository = personDapperRepository;

            personRepository = _personRepository;

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

            per = _per;

        }

```

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

![image.png](https://upload-images.jianshu.io/upload_images/1727627-aaa3f0df77e2a1b8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

```

namespace Demo.Repositorys

{

    public class  PersonRepository: NpocoRepositoryBase,IPersonRepository

    {

    public  PersonRepository()

        {

            Db = DataManager.GetDb();

        }

```

你可能感兴趣的:(abp中建立Npoco仓储)