diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 42e4b28516..3c3336de1f 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -238,9 +238,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Dashboards", "src\Volo.Abp.AspNetCore.Mvc.UI.Dashboards\Volo.Abp.AspNetCore.Mvc.UI.Dashboards.csproj", "{054D766D-5992-460E-A4D8-936D80BE2C1A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ldap", "src\Volo.Abp.Ldap\Volo.Abp.Ldap.csproj", "{4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Ldap", "src\Volo.Abp.Ldap\Volo.Abp.Ldap.csproj", "{4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ldap.Tests", "test\Volo.Abp.Ldap.Tests\Volo.Abp.Ldap.Tests.csproj", "{38FB8F75-426E-4265-8D0E-E121837B6FCC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Ldap.Tests", "test\Volo.Abp.Ldap.Tests\Volo.Abp.Ldap.Tests.csproj", "{38FB8F75-426E-4265-8D0E-E121837B6FCC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Dapper", "src\Volo.Abp.Dapper\Volo.Abp.Dapper.csproj", "{D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Dapper.Tests", "test\Volo.Abp.Dapper.Tests\Volo.Abp.Dapper.Tests.csproj", "{E026A085-D881-4AE0-9F08-422AC3903BD7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -720,6 +724,14 @@ Global {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Debug|Any CPU.Build.0 = Debug|Any CPU {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Release|Any CPU.ActiveCfg = Release|Any CPU {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Release|Any CPU.Build.0 = Release|Any CPU + {D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D863A3C3-CC1D-426F-BDD4-02E7AE2A3170}.Release|Any CPU.Build.0 = Release|Any CPU + {E026A085-D881-4AE0-9F08-422AC3903BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E026A085-D881-4AE0-9F08-422AC3903BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E026A085-D881-4AE0-9F08-422AC3903BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E026A085-D881-4AE0-9F08-422AC3903BD7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -843,6 +855,8 @@ Global {054D766D-5992-460E-A4D8-936D80BE2C1A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {4DADBBD2-4C63-4C90-9661-EBF6252A7D6F} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {38FB8F75-426E-4265-8D0E-E121837B6FCC} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {D863A3C3-CC1D-426F-BDD4-02E7AE2A3170} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {E026A085-D881-4AE0-9F08-422AC3903BD7} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj b/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj new file mode 100644 index 0000000000..849dc33c60 --- /dev/null +++ b/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj @@ -0,0 +1,24 @@ + + + + + + netstandard2.0 + Volo.Abp.Dapper + Volo.Abp.Dapper + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Dapper/AbpDapperModule.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Dapper/AbpDapperModule.cs new file mode 100644 index 0000000000..17045fd12b --- /dev/null +++ b/framework/src/Volo.Abp.Dapper/Volo/Abp/Dapper/AbpDapperModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Domain; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Dapper +{ + [DependsOn( + typeof(AbpDddDomainModule), + typeof(AbpEntityFrameworkCoreModule))] + public class AbpDapperModule : AbpModule + { + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs new file mode 100644 index 0000000000..cdb03f8515 --- /dev/null +++ b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs @@ -0,0 +1,23 @@ +using System.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Uow; + +namespace Volo.Abp.Domain.Repositories.Dapper +{ + public class DapperRepository : IDapperRepository, IUnitOfWorkEnabled + where TDbContext : IEfCoreDbContext + { + private readonly IDbContextProvider _dbContextProvider; + + public DapperRepository(IDbContextProvider dbContextProvider) + { + _dbContextProvider = dbContextProvider; + } + + public IDbConnection DbConnection => _dbContextProvider.GetDbContext().Database.GetDbConnection(); + + public IDbTransaction DbTransaction => _dbContextProvider.GetDbContext().Database.CurrentTransaction?.GetDbTransaction(); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs new file mode 100644 index 0000000000..f45be08b54 --- /dev/null +++ b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs @@ -0,0 +1,11 @@ +using System.Data; + +namespace Volo.Abp.Domain.Repositories.Dapper +{ + public interface IDapperRepository + { + IDbConnection DbConnection { get; } + + IDbTransaction DbTransaction { get; } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj b/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj new file mode 100644 index 0000000000..c531932479 --- /dev/null +++ b/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj @@ -0,0 +1,24 @@ + + + + netcoreapp2.2 + Volo.Abp.Dapper.Tests + Volo.Abp.Dapper.Tests + true + false + false + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/AbpDapperTestModule.cs b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/AbpDapperTestModule.cs new file mode 100644 index 0000000000..02b7575052 --- /dev/null +++ b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/AbpDapperTestModule.cs @@ -0,0 +1,17 @@ +using Volo.Abp.Autofac; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Dapper +{ + [DependsOn( + typeof(AbpEntityFrameworkCoreTestModule), + typeof(AbpDapperModule), + typeof(AbpAutofacModule))] + public class AbpDapperTestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/DapperTestBase.cs b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/DapperTestBase.cs new file mode 100644 index 0000000000..3fa387cec2 --- /dev/null +++ b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/DapperTestBase.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.Dapper +{ + public abstract class DapperTestBase : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs new file mode 100644 index 0000000000..3621f9301e --- /dev/null +++ b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Dapper; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories.Dapper; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.TestApp.EntityFrameworkCore; + +namespace Volo.Abp.Dapper.Repositories +{ + public class PersonDapperRepository : DapperRepository, ITransientDependency + { + public PersonDapperRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public virtual async Task> GetAllPersonNames() + { + return (await DbConnection.QueryAsync("select Name from People", transaction: DbTransaction)) + .ToList(); + } + + public virtual async Task UpdatePersonNames(string name) + { + return await DbConnection.ExecuteAsync("update People set Name = @NewName", new {NewName = name}, + DbTransaction); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository_Tests.cs b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository_Tests.cs new file mode 100644 index 0000000000..3b5a7a4dd3 --- /dev/null +++ b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository_Tests.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.TestApp; +using Volo.Abp.Uow; +using Xunit; + +namespace Volo.Abp.Dapper.Repositories +{ + public class PersonDapperRepository_Tests : DapperTestBase + { + [Fact] + public async Task GetAllPersonNames_Test() + { + var allNames = await GetRequiredService().GetAllPersonNames(); + allNames.ShouldNotBeEmpty(); + allNames.ShouldContain(x => x == "Douglas"); + allNames.ShouldContain(x => x == "John-Deleted"); + allNames.ShouldContain(x => x == $"{TestDataBuilder.TenantId1}-Person1"); + allNames.ShouldContain(x => x == $"{TestDataBuilder.TenantId1}-Person2"); + } + + [Fact] + public async Task UpdatePersonNames_Test() + { + var personDapperRepository = GetRequiredService(); + await personDapperRepository.UpdatePersonNames("test"); + + var allNames = await personDapperRepository.GetAllPersonNames(); + allNames.ShouldNotBeEmpty(); + allNames.ShouldAllBe(x => x == "test"); + } + + [Fact] + public async Task Dapper_Transaction_Test() + { + var unitOfWorkManager = GetRequiredService(); + var personDapperRepository = GetRequiredService(); + + using (var uow = unitOfWorkManager.Begin(new UnitOfWorkOptions + { + IsTransactional = true + })) + { + await personDapperRepository.UpdatePersonNames("test"); + await uow.RollbackAsync(); + } + + var allNames = await personDapperRepository.GetAllPersonNames(); + allNames.ShouldAllBe(x => x != "test"); + } + } +} \ No newline at end of file