diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj
index 857a6a409c..9a42aec87b 100644
--- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj
+++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk.EntityFrameworkCore.csproj
@@ -12,6 +12,7 @@
+
diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs
index b523edddc9..82e3e582b0 100644
--- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs
+++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskDbContext.cs
@@ -2,14 +2,20 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.MultiTenancy.EntityFrameworkCore;
namespace AbpDesk.EntityFrameworkCore
{
[ConnectionStringName(ConnectionStrings.DefaultConnectionStringName)] //Explicitly declares this module always uses the default connection string
- public class AbpDeskDbContext : AbpDbContext
+ public class AbpDeskDbContext : AbpDbContext, IMultiTenancyDbContext
{
public DbSet Tickets { get; set; }
+ public DbSet Tenants { get; set; }
+
+ public DbSet TenantConnectionStrings { get; set; }
+
public AbpDeskDbContext(DbContextOptions options)
: base(options)
{
@@ -20,6 +26,8 @@ namespace AbpDesk.EntityFrameworkCore
{
base.OnModelCreating(modelBuilder);
+ this.ConfigureAbpMultiTenancy(modelBuilder);
+
//Use different classes to map each entity type?
modelBuilder.Entity(b =>
{
diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs
index 3538a2186e..022d8cfc3a 100644
--- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs
+++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/AbpDesk/EntityFrameworkCore/AbpDeskEntityFrameworkCoreModule.cs
@@ -1,10 +1,15 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
+using Volo.Abp.MultiTenancy.EntityFrameworkCore;
namespace AbpDesk.EntityFrameworkCore
{
- [DependsOn(typeof(AbpDeskDomainModule), typeof(AbpEntityFrameworkCoreModule))]
+ [DependsOn(
+ typeof(AbpDeskDomainModule),
+ typeof(AbpEntityFrameworkCoreModule),
+ typeof(AbpMultiTenancyEntityFrameworkCoreModule)
+ )]
public class AbpDeskEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs
new file mode 100644
index 0000000000..087141c5f3
--- /dev/null
+++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.Designer.cs
@@ -0,0 +1,92 @@
+//
+using AbpDesk.EntityFrameworkCore;
+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;
+
+namespace AbpDesk.EntityFrameworkCore.Migrations
+{
+ [DbContext(typeof(AbpDeskDbContext))]
+ [Migration("20180105184326_MultiTenancyModuleAdded")]
+ partial class MultiTenancyModuleAdded
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "2.0.0-rtm-26452")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("AbpDesk.Tickets.Ticket", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Body")
+ .HasMaxLength(65536);
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Title")
+ .IsRequired()
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.ToTable("DskTickets");
+ });
+
+ modelBuilder.Entity("Volo.Abp.MultiTenancy.Tenant", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(64);
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name");
+
+ b.ToTable("MtTenants");
+ });
+
+ modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256);
+
+ b.Property("TenantId");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(1024);
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("MtTenantConnectionStrings");
+ });
+
+ modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b =>
+ {
+ b.HasOne("Volo.Abp.MultiTenancy.Tenant")
+ .WithMany("ConnectionStrings")
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs
new file mode 100644
index 0000000000..3f9eae2ed0
--- /dev/null
+++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/20180105184326_MultiTenancyModuleAdded.cs
@@ -0,0 +1,63 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using System;
+using System.Collections.Generic;
+
+namespace AbpDesk.EntityFrameworkCore.Migrations
+{
+ public partial class MultiTenancyModuleAdded : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "MtTenants",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MtTenants", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "MtTenantConnectionStrings",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false),
+ TenantId = table.Column(type: "uniqueidentifier", nullable: false),
+ Value = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_MtTenantConnectionStrings", x => x.Id);
+ table.ForeignKey(
+ name: "FK_MtTenantConnectionStrings_MtTenants_TenantId",
+ column: x => x.TenantId,
+ principalTable: "MtTenants",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MtTenantConnectionStrings_TenantId",
+ table: "MtTenantConnectionStrings",
+ column: "TenantId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_MtTenants_Name",
+ table: "MtTenants",
+ column: "Name");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "MtTenantConnectionStrings");
+
+ migrationBuilder.DropTable(
+ name: "MtTenants");
+ }
+ }
+}
diff --git a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs
index b84a4c0fca..d355af3c6a 100644
--- a/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs
+++ b/src/AbpDesk/AbpDesk.EntityFrameworkCore/Migrations/AbpDeskDbContextModelSnapshot.cs
@@ -1,6 +1,12 @@
-using Microsoft.EntityFrameworkCore;
+//
+using AbpDesk.EntityFrameworkCore;
+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;
namespace AbpDesk.EntityFrameworkCore.Migrations
{
@@ -9,8 +15,9 @@ namespace AbpDesk.EntityFrameworkCore.Migrations
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
+#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "1.1.0-rtm-22752")
+ .HasAnnotation("ProductVersion", "2.0.0-rtm-26452")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("AbpDesk.Tickets.Ticket", b =>
@@ -32,6 +39,53 @@ namespace AbpDesk.EntityFrameworkCore.Migrations
b.ToTable("DskTickets");
});
+
+ modelBuilder.Entity("Volo.Abp.MultiTenancy.Tenant", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(64);
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name");
+
+ b.ToTable("MtTenants");
+ });
+
+ modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256);
+
+ b.Property("TenantId");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(1024);
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("MtTenantConnectionStrings");
+ });
+
+ modelBuilder.Entity("Volo.Abp.MultiTenancy.TenantConnectionString", b =>
+ {
+ b.HasOne("Volo.Abp.MultiTenancy.Tenant")
+ .WithMany("ConnectionStrings")
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+#pragma warning restore 612, 618
}
}
}
diff --git a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs
index 06a09c8075..f7ff4b87e8 100644
--- a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs
+++ b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs
@@ -7,7 +7,9 @@ namespace Microsoft.Extensions.DependencyInjection
{
public static class AbpEfCoreServiceCollectionExtensions
{
- public static IServiceCollection AddAbpDbContext(this IServiceCollection services, Action optionsBuilder = null) //Created overload instead of default parameter
+ public static IServiceCollection AddAbpDbContext(
+ this IServiceCollection services,
+ Action optionsBuilder = null)
where TDbContext : AbpDbContext
{
services.AddMemoryCache();
diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
index 8ed4a53b44..869d090176 100644
--- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
+++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
@@ -12,7 +12,7 @@ using Volo.Abp.Threading;
namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
public class EfCoreRepository : EfCoreRepository, IEfCoreRepository
- where TDbContext : AbpDbContext
+ where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
public EfCoreRepository(IDbContextProvider dbContextProvider)
@@ -25,12 +25,12 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
IEfCoreRepository,
ISupportsExplicitLoading
- where TDbContext : AbpDbContext
+ where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
public virtual DbSet DbSet => DbContext.Set();
- DbContext IEfCoreRepository.DbContext => DbContext;
+ DbContext IEfCoreRepository.DbContext => DbContext.As();
protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs
index 172461a913..f2612f4b4b 100644
--- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs
+++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs
@@ -1,4 +1,3 @@
-using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EntityFrameworkCore.DependencyInjection
diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs
index d975596df1..c4655fddd0 100644
--- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs
+++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs
@@ -1,7 +1,7 @@
namespace Volo.Abp.EntityFrameworkCore
{
public interface IDbContextProvider
- where TDbContext : AbpDbContext
+ where TDbContext : IEfCoreDbContext
{
TDbContext GetDbContext();
}
diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs
index 880d4112e3..7cba957724 100644
--- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs
+++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IEfCoreDbContext.cs
@@ -1,14 +1,86 @@
-using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Internal;
namespace Volo.Abp.EntityFrameworkCore
{
- public interface IEfCoreDbContext
+ public interface IEfCoreDbContext : IDisposable, IInfrastructure, IDbContextDependencies, IDbSetCache, IDbContextPoolable
{
+ EntityEntry Attach([NotNull] TEntity entity) where TEntity : class;
+
+ EntityEntry Attach([NotNull] object entity);
+
int SaveChanges();
int SaveChanges(bool acceptAllChangesOnSuccess);
+ Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default);
+
+ Task SaveChangesAsync(CancellationToken cancellationToken = default);
+
DbSet Set()
where T: class;
+
+ DatabaseFacade Database { get; }
+
+ ChangeTracker ChangeTracker { get; }
+
+ EntityEntry Add([NotNull] object entity);
+
+ EntityEntry Add([NotNull] TEntity entity) where TEntity : class;
+
+ Task AddAsync([NotNull] object entity, CancellationToken cancellationToken = default);
+
+ Task> AddAsync([NotNull] TEntity entity, CancellationToken cancellationToken = default) where TEntity : class;
+
+ void AddRange([NotNull] IEnumerable