Browse Source

Unit tests and improvements for UOW.

pull/115/head
Halil İbrahim Kalkan 9 years ago
parent
commit
d992036159
  1. 12
      Volo.Abp.sln
  2. 32
      src/Volo.Abp.TestBase/AbpTestBaseWithServiceProvider.cs
  3. 7
      src/Volo.Abp/Volo/Abp/Uow/ITransactionApi.cs
  4. 95
      src/Volo.Abp/Volo/Abp/Uow/UnitOfWork.cs
  5. 8
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Class1.cs
  6. 37
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Migrations/20170927075606_Initial_Migration.Designer.cs
  7. 30
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Migrations/20170927075606_Initial_Migration.cs
  8. 36
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Migrations/SecondDbContextModelSnapshot.cs
  9. 32
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo.Abp.EntityFrameworkCore.Tests.SecondContext.csproj
  10. 29
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs
  11. 9
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/BookInSecondDbContext.cs
  12. 27
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondContextTestDataBuilder.cs
  13. 14
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs
  14. 15
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContextFactory.cs
  15. 66
      test/Volo.Abp.EntityFrameworkCore.Tests/Migrations/20170927080244_Initial_Migration.Designer.cs
  16. 60
      test/Volo.Abp.EntityFrameworkCore.Tests/Migrations/20170927080244_Initial_Migration.cs
  17. 65
      test/Volo.Abp.EntityFrameworkCore.Tests/Migrations/TestAppDbContextModelSnapshot.cs
  18. 5
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj
  19. 10
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs
  20. 11
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/Basic_Repository_Tests.cs
  21. 36
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Transaction_Tests.cs
  22. 15
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContextFactory.cs
  23. 2
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Phone.cs

12
Volo.Abp.sln

@ -138,8 +138,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Domain",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Identity.Domain.Shared", "src\Volo.Abp.Identity.Domain.Shared\Volo.Abp.Identity.Domain.Shared.csproj", "{DF676F73-3FC9-46CE-909A-2D75E19982AD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EntityFrameworkCore.Tests", "test\Volo.Abp.EntityFrameworkCore.Tests\Volo.Abp.EntityFrameworkCore.Tests.csproj", "{3AF7C7F5-6513-47D4-8DD0-6E1AF14568D8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleConsoleDemo", "test\SimpleConsoleDemo\SimpleConsoleDemo.csproj", "{2B48CF90-DBDB-469F-941C-5B5AECEEACE0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EntityFrameworkCore.Tests", "test\Volo.Abp.EntityFrameworkCore.Tests\Volo.Abp.EntityFrameworkCore.Tests.csproj", "{3AF7C7F5-6513-47D4-8DD0-6E1AF14568D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleConsoleDemo", "test\SimpleConsoleDemo\SimpleConsoleDemo.csproj", "{2B48CF90-DBDB-469F-941C-5B5AECEEACE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EntityFrameworkCore.Tests.SecondContext", "test\Volo.Abp.EntityFrameworkCore.Tests.SecondContext\Volo.Abp.EntityFrameworkCore.Tests.SecondContext.csproj", "{127FC2BF-DC40-4370-B845-16088328264C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -359,6 +362,10 @@ Global
{2B48CF90-DBDB-469F-941C-5B5AECEEACE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B48CF90-DBDB-469F-941C-5B5AECEEACE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B48CF90-DBDB-469F-941C-5B5AECEEACE0}.Release|Any CPU.Build.0 = Release|Any CPU
{127FC2BF-DC40-4370-B845-16088328264C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{127FC2BF-DC40-4370-B845-16088328264C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{127FC2BF-DC40-4370-B845-16088328264C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{127FC2BF-DC40-4370-B845-16088328264C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -426,6 +433,7 @@ Global
{DF676F73-3FC9-46CE-909A-2D75E19982AD} = {1895A5C9-50D4-4568-9A3A-14657E615A5E}
{3AF7C7F5-6513-47D4-8DD0-6E1AF14568D8} = {37087D1B-3693-4E96-983D-A69F210BDE53}
{2B48CF90-DBDB-469F-941C-5B5AECEEACE0} = {37087D1B-3693-4E96-983D-A69F210BDE53}
{127FC2BF-DC40-4370-B845-16088328264C} = {37087D1B-3693-4E96-983D-A69F210BDE53}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

32
src/Volo.Abp.TestBase/AbpTestBaseWithServiceProvider.cs

@ -10,12 +10,17 @@ namespace Volo.Abp.TestBase
protected abstract IServiceProvider ServiceProvider { get; }
protected virtual void WithUnitOfWork(Action action)
{
WithUnitOfWork(new UnitOfWorkOptions(), action);
}
protected virtual void WithUnitOfWork(UnitOfWorkOptions options, Action action)
{
using (var scope = ServiceProvider.CreateScope())
{
var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using (var uow = uowManager.Begin())
using (var uow = uowManager.Begin(options))
{
action();
@ -24,13 +29,18 @@ namespace Volo.Abp.TestBase
}
}
protected virtual async Task WithUnitOfWorkAsync(Func<Task> action)
protected virtual Task WithUnitOfWorkAsync(Func<Task> func)
{
return WithUnitOfWorkAsync(new UnitOfWorkOptions(), func);
}
protected virtual async Task WithUnitOfWorkAsync(UnitOfWorkOptions options, Func<Task> action)
{
using (var scope = ServiceProvider.CreateScope())
{
var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using (var uow = uowManager.Begin())
using (var uow = uowManager.Begin(options))
{
await action();
@ -40,12 +50,17 @@ namespace Volo.Abp.TestBase
}
protected virtual TResult WithUnitOfWork<TResult>(Func<TResult> func)
{
return WithUnitOfWork(new UnitOfWorkOptions(), func);
}
protected virtual TResult WithUnitOfWork<TResult>(UnitOfWorkOptions options, Func<TResult> func)
{
using (var scope = ServiceProvider.CreateScope())
{
var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using (var uow = uowManager.Begin())
using (var uow = uowManager.Begin(options))
{
var result = func();
uow.Complete();
@ -54,13 +69,18 @@ namespace Volo.Abp.TestBase
}
}
protected virtual async Task<TResult> WithUnitOfWorkAsync<TResult>(Func<Task<TResult>> func)
protected virtual Task<TResult> WithUnitOfWorkAsync<TResult>(Func<Task<TResult>> func)
{
return WithUnitOfWorkAsync(new UnitOfWorkOptions(), func);
}
protected virtual async Task<TResult> WithUnitOfWorkAsync<TResult>(UnitOfWorkOptions options, Func<Task<TResult>> func)
{
using (var scope = ServiceProvider.CreateScope())
{
var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using (var uow = uowManager.Begin())
using (var uow = uowManager.Begin(options))
{
var result = await func();
await uow.CompleteAsync();

7
src/Volo.Abp/Volo/Abp/Uow/ITransactionApi.cs

@ -1,13 +1,12 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
namespace Volo.Abp.Uow
{
public interface ITransactionApi
public interface ITransactionApi : IDisposable
{
void Commit();
Task CommitAsync();
void Dispose();
}
}

95
src/Volo.Abp/Volo/Abp/Uow/UnitOfWork.cs

@ -141,15 +141,7 @@ namespace Volo.Abp.Uow
_isRolledback = true;
foreach (var databaseApi in _databaseApis.Values)
{
(databaseApi as ISupportsRollback)?.Rollback();
}
foreach (var transactionApi in _transactionApis.Values)
{
(transactionApi as ISupportsRollback)?.Rollback();
}
RollbackAll();
}
public virtual async Task RollbackAsync(CancellationToken cancellationToken = default(CancellationToken))
@ -161,21 +153,7 @@ namespace Volo.Abp.Uow
_isRolledback = true;
foreach (var databaseApi in _databaseApis.Values)
{
if (databaseApi is ISupportsRollback)
{
await (databaseApi as ISupportsRollback).RollbackAsync(cancellationToken);
}
}
foreach (var transactionApi in _transactionApis.Values)
{
if (transactionApi is ISupportsRollback)
{
await (transactionApi as ISupportsRollback).RollbackAsync(cancellationToken);
}
}
await RollbackAllAsync(cancellationToken);
}
public IDatabaseApi FindDatabaseApi(string key)
@ -256,6 +234,8 @@ namespace Volo.Abp.Uow
_isDisposed = true;
DisposeTransactions();
if (!_isCompleted || _exception != null)
{
OnFailed();
@ -264,6 +244,20 @@ namespace Volo.Abp.Uow
OnDisposed();
}
private void DisposeTransactions()
{
foreach (var transactionApi in _transactionApis.Values)
{
try
{
transactionApi.Dispose();
}
catch
{
}
}
}
private void PreventMultipleComplete()
{
if (_isCompleted)
@ -274,9 +268,53 @@ namespace Volo.Abp.Uow
_isCompleted = true;
}
public override string ToString()
protected virtual void RollbackAll()
{
return $"[UnitOfWork {Id}]";
foreach (var databaseApi in _databaseApis.Values)
{
try
{
(databaseApi as ISupportsRollback)?.Rollback();
}
catch { }
}
foreach (var transactionApi in _transactionApis.Values)
{
try
{
(transactionApi as ISupportsRollback)?.Rollback();
}
catch { }
}
}
protected virtual async Task RollbackAllAsync(CancellationToken cancellationToken)
{
foreach (var databaseApi in _databaseApis.Values)
{
if (databaseApi is ISupportsRollback)
{
try
{
await (databaseApi as ISupportsRollback).RollbackAsync(cancellationToken);
}
catch { }
}
}
foreach (var transactionApi in _transactionApis.Values)
{
if (transactionApi is ISupportsRollback)
{
try
{
await (transactionApi as ISupportsRollback).RollbackAsync(cancellationToken);
}
catch { }
}
}
}
protected virtual void CommitTransactions()
@ -294,5 +332,10 @@ namespace Volo.Abp.Uow
await transaction.CommitAsync();
}
}
public override string ToString()
{
return $"[UnitOfWork {Id}]";
}
}
}

8
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Class1.cs

@ -0,0 +1,8 @@
using System;
namespace Volo.Abp.EntityFrameworkCore.Tests.SecondContext
{
public class Class1
{
}
}

37
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Migrations/20170927075606_Initial_Migration.Designer.cs

@ -0,0 +1,37 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using System;
using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext;
namespace Volo.Abp.EntityFrameworkCore.Tests.SecondContext.Migrations
{
[DbContext(typeof(SecondDbContext))]
[Migration("20170927075606_Initial_Migration")]
partial class Initial_Migration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
modelBuilder.Entity("Volo.Abp.EntityFrameworkCore.TestApp.SecondContext.BookInSecondDbContext", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("Books");
});
#pragma warning restore 612, 618
}
}
}

30
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Migrations/20170927075606_Initial_Migration.cs

@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;
namespace Volo.Abp.EntityFrameworkCore.Tests.SecondContext.Migrations
{
public partial class Initial_Migration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Books",
columns: table => new
{
Id = table.Column<Guid>(type: "BLOB", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Books", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Books");
}
}
}

36
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Migrations/SecondDbContextModelSnapshot.cs

@ -0,0 +1,36 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using System;
using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext;
namespace Volo.Abp.EntityFrameworkCore.Tests.SecondContext.Migrations
{
[DbContext(typeof(SecondDbContext))]
partial class SecondDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
modelBuilder.Entity("Volo.Abp.EntityFrameworkCore.TestApp.SecondContext.BookInSecondDbContext", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("Books");
});
#pragma warning restore 612, 618
}
}
}

32
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo.Abp.EntityFrameworkCore.Tests.SecondContext.csproj

@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<AssemblyName>Volo.Abp.EntityFrameworkCore.Tests.SecondContext</AssemblyName>
<PackageId>Volo.Abp.EntityFrameworkCore.Tests.SecondContext</PackageId>
<PreserveCompilationContext>true</PreserveCompilationContext>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.EntityFrameworkCore\Volo.Abp.EntityFrameworkCore.csproj" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" />
</ItemGroup>
</Project>

29
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/AbpEfCoreTestSecondContextModule.cs

@ -0,0 +1,29 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
{
[DependsOn(typeof(AbpEntityFrameworkCoreModule))]
public class AbpEfCoreTestSecondContextModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddAssemblyOf<AbpEfCoreTestSecondContextModule>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
SeedTestData(context);
}
private static void SeedTestData(ApplicationInitializationContext context)
{
using (var scope = context.ServiceProvider.CreateScope())
{
scope.ServiceProvider
.GetRequiredService<SecondContextTestDataBuilder>()
.Build();
}
}
}
}

9
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/BookInSecondDbContext.cs

@ -0,0 +1,9 @@
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
{
public class BookInSecondDbContext : AggregateRoot
{
public string Name { get; set; }
}
}

27
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondContextTestDataBuilder.cs

@ -0,0 +1,27 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
{
public class SecondContextTestDataBuilder : ITransientDependency
{
private readonly IRepository<BookInSecondDbContext> _bookRepository;
private readonly IGuidGenerator _guidGenerator;
public SecondContextTestDataBuilder(IRepository<BookInSecondDbContext> bookRepository, IGuidGenerator guidGenerator)
{
_bookRepository = bookRepository;
_guidGenerator = guidGenerator;
}
public void Build()
{
_bookRepository.Insert(new BookInSecondDbContext
{
Id = _guidGenerator.Create(),
Name = "TestBook1"
});
}
}
}

14
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs

@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
{
public class SecondDbContext : AbpDbContext<SecondDbContext>
{
public DbSet<BookInSecondDbContext> Books { get; set; }
public SecondDbContext(DbContextOptions<SecondDbContext> options)
: base(options)
{
}
}
}

15
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContextFactory.cs

@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
{
public class SecondDbContextFactory : IDesignTimeDbContextFactory<SecondDbContext>
{
public SecondDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<SecondDbContext>();
builder.UseSqlite(@"Data Source=d:\temp\VoloAbpEfCoreTestModule.db;");
return new SecondDbContext(builder.Options);
}
}
}

66
test/Volo.Abp.EntityFrameworkCore.Tests/Migrations/20170927080244_Initial_Migration.Designer.cs

@ -0,0 +1,66 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using System;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.TestApp.EntityFrameworkCore;
namespace Volo.Abp.EntityFrameworkCore.Tests.Migrations
{
[DbContext(typeof(TestAppDbContext))]
[Migration("20170927080244_Initial_Migration")]
partial class Initial_Migration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
modelBuilder.Entity("Volo.Abp.TestApp.Domain.Person", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Age");
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("People");
});
modelBuilder.Entity("Volo.Abp.TestApp.Domain.Phone", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Number");
b.Property<Guid>("PersonId");
b.Property<int>("Type");
b.HasKey("Id");
b.HasIndex("PersonId");
b.ToTable("AppPhones");
});
modelBuilder.Entity("Volo.Abp.TestApp.Domain.Phone", b =>
{
b.HasOne("Volo.Abp.TestApp.Domain.Person")
.WithMany("Phones")
.HasForeignKey("PersonId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

60
test/Volo.Abp.EntityFrameworkCore.Tests/Migrations/20170927080244_Initial_Migration.cs

@ -0,0 +1,60 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;
namespace Volo.Abp.EntityFrameworkCore.Tests.Migrations
{
public partial class Initial_Migration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "People",
columns: table => new
{
Id = table.Column<Guid>(type: "BLOB", nullable: false),
Age = table.Column<int>(type: "INTEGER", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_People", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppPhones",
columns: table => new
{
Id = table.Column<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Number = table.Column<string>(type: "TEXT", nullable: true),
PersonId = table.Column<Guid>(type: "BLOB", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AppPhones", x => x.Id);
table.ForeignKey(
name: "FK_AppPhones_People_PersonId",
column: x => x.PersonId,
principalTable: "People",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AppPhones_PersonId",
table: "AppPhones",
column: "PersonId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AppPhones");
migrationBuilder.DropTable(
name: "People");
}
}
}

65
test/Volo.Abp.EntityFrameworkCore.Tests/Migrations/TestAppDbContextModelSnapshot.cs

@ -0,0 +1,65 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using System;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.TestApp.EntityFrameworkCore;
namespace Volo.Abp.EntityFrameworkCore.Tests.Migrations
{
[DbContext(typeof(TestAppDbContext))]
partial class TestAppDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
modelBuilder.Entity("Volo.Abp.TestApp.Domain.Person", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Age");
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("People");
});
modelBuilder.Entity("Volo.Abp.TestApp.Domain.Phone", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Number");
b.Property<Guid>("PersonId");
b.Property<int>("Type");
b.HasKey("Id");
b.HasIndex("PersonId");
b.ToTable("AppPhones");
});
modelBuilder.Entity("Volo.Abp.TestApp.Domain.Phone", b =>
{
b.HasOne("Volo.Abp.TestApp.Domain.Person")
.WithMany("Phones")
.HasForeignKey("PersonId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

5
test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj

@ -15,16 +15,19 @@
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.EntityFrameworkCore\Volo.Abp.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
<ProjectReference Include="..\Volo.Abp.EntityFrameworkCore.Tests.SecondContext\Volo.Abp.EntityFrameworkCore.Tests.SecondContext.csproj" />
<ProjectReference Include="..\Volo.Abp.TestApp\Volo.Abp.TestApp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Volo\Abp\TestApp\EntityFrameworkCore\" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
</ItemGroup>
</Project>

10
test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs

@ -2,6 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Autofac;
using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp;
using Volo.Abp.TestApp.EntityFrameworkCore;
@ -11,6 +12,7 @@ namespace Volo.Abp.EntityFrameworkCore
[DependsOn(typeof(AbpEntityFrameworkCoreModule))]
[DependsOn(typeof(TestAppModule))]
[DependsOn(typeof(AbpAutofacModule))]
[DependsOn(typeof(AbpEfCoreTestSecondContextModule))]
public class AbpEntityFrameworkCoreTestModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
@ -22,6 +24,11 @@ namespace Volo.Abp.EntityFrameworkCore
options.WithDefaultRepositories();
});
services.AddAbpDbContext<SecondDbContext>(options =>
{
options.WithDefaultRepositories();
});
var inMemorySqlite = new SqliteConnection("Data Source=:memory:");
inMemorySqlite.Open();
@ -36,7 +43,8 @@ namespace Volo.Abp.EntityFrameworkCore
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
context.ServiceProvider.GetRequiredService<TestAppDbContext>().Database.EnsureCreated();
context.ServiceProvider.GetRequiredService<TestAppDbContext>().Database.Migrate();
context.ServiceProvider.GetRequiredService<SecondDbContext>().Database.Migrate();
}
}
}

11
test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/Basic_Repository_Tests.cs

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext;
using Volo.Abp.TestApp.Domain;
using Xunit;
@ -12,18 +13,26 @@ namespace Volo.Abp.EntityFrameworkCore.Repositories
public class Basic_Repository_Tests : EntityFrameworkCoreTestBase
{
private readonly IRepository<Person> _personRepository;
private readonly IRepository<BookInSecondDbContext> _bookRepository;
public Basic_Repository_Tests()
{
_personRepository = ServiceProvider.GetRequiredService<IRepository<Person>>();
_bookRepository = ServiceProvider.GetRequiredService<IRepository<BookInSecondDbContext>>();
}
[Fact]
public void GetList()
public void GetPersonList()
{
_personRepository.GetList().Any().ShouldBeTrue();
}
[Fact]
public void GetBookList()
{
_bookRepository.GetList().Any().ShouldBeTrue();
}
[Fact]
public async Task InsertAsync()
{

36
test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Transaction_Tests.cs

@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.Uow;
using Xunit;
@ -12,11 +13,13 @@ namespace Volo.Abp.EntityFrameworkCore
public class Transaction_Tests : EntityFrameworkCoreTestBase
{
private readonly IRepository<Person> _personRepository;
private readonly IRepository<BookInSecondDbContext> _bookRepository;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public Transaction_Tests()
{
_personRepository = ServiceProvider.GetRequiredService<IRepository<Person>>();
_bookRepository = ServiceProvider.GetRequiredService<IRepository<BookInSecondDbContext>>();
_unitOfWorkManager = ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
}
@ -28,7 +31,7 @@ namespace Volo.Abp.EntityFrameworkCore
try
{
await WithUnitOfWorkAsync(async () =>
await WithUnitOfWorkAsync(new UnitOfWorkOptions { IsTransactional = true }, async () =>
{
await _personRepository.InsertAsync(new Person(personId, "Adam", 42));
throw new Exception(exceptionMessage);
@ -48,15 +51,44 @@ namespace Volo.Abp.EntityFrameworkCore
{
var personId = Guid.NewGuid();
await WithUnitOfWorkAsync(async () =>
await WithUnitOfWorkAsync(new UnitOfWorkOptions { IsTransactional = true }, async () =>
{
_unitOfWorkManager.Current.ShouldNotBeNull();
await _personRepository.InsertAsync(new Person(personId, "Adam", 42));
await _unitOfWorkManager.Current.RollbackAsync();
});
var person = await _personRepository.FindAsync(personId);
person.ShouldBeNull();
}
[Fact]
public async Task Should_Rollback_Transaction_Manually_With_Double_DbContext_Transaction()
{
var personId = Guid.NewGuid();
var bookId = Guid.NewGuid();
using (var scope = ServiceProvider.CreateScope())
{
var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using (uowManager.Begin(new UnitOfWorkOptions { IsTransactional = true }))
{
_unitOfWorkManager.Current.ShouldNotBeNull();
await _personRepository.InsertAsync(new Person(personId, "Adam", 42));
await _bookRepository.InsertAsync(new BookInSecondDbContext { Id = bookId, Name = bookId.ToString() });
await _unitOfWorkManager.Current.SaveChangesAsync();
//Will automatically rollback since not called the Complete!
}
}
(await _personRepository.FindAsync(personId)).ShouldBeNull();
(await _bookRepository.FindAsync(bookId)).ShouldBeNull();
}
}
}

15
test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContextFactory.cs

@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
namespace Volo.Abp.TestApp.EntityFrameworkCore
{
public class TestAppDbContextFactory : IDesignTimeDbContextFactory<TestAppDbContext>
{
public TestAppDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<TestAppDbContext>();
builder.UseSqlite(@"Data Source=d:\temp\VoloAbpEfCoreTestModule.db;");
return new TestAppDbContext(builder.Options);
}
}
}

2
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Phone.cs

@ -1,8 +1,10 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.TestApp.Domain
{
[Table("AppPhones")]
public class Phone : Entity<long>
{
public virtual Guid PersonId { get; set; }

Loading…
Cancel
Save