abp中建立Npoco仓储

2019-07-09  本文已影响0人  悦_547b

因为一直使用的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();

        }

```

上一篇下一篇

猜你喜欢

热点阅读