Skip to content

Commit

Permalink
Multi provider support for EF (SQL and Sqlite)
Browse files Browse the repository at this point in the history
- Do not add the DbContext in DataAccess.EF any more
- Add projects for MsSql and Sqlite which add the DbContext
- Use the config value Database.Provider to determine which provider will be added
- Delete all existing migrations
- Generate migrations for each provider separately
- Manually add trigger creation for concurrent modifications with the BaseEntity.Version field to Sqlite migration (dotnet/efcore#12260 (comment))
- Use Sqlite for integration and api tests
  • Loading branch information
taconaut committed May 1, 2019
1 parent 06bbcc9 commit 339ca7f
Show file tree
Hide file tree
Showing 38 changed files with 872 additions and 2,205 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Sppd.TeamTuner.Infrastructure.DataAccess.EF.Migrations
namespace Sppd.TeamTuner.Infrastructure.DataAccess.EF.MsSql.Migrations
{
public partial class Initial : Migration
{
Expand All @@ -19,6 +19,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false)
},
constraints: table =>
Expand All @@ -38,6 +39,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false),
Avatar = table.Column<byte[]>(nullable: true),
Description = table.Column<string>(maxLength: 2000, nullable: true)
Expand All @@ -59,6 +61,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false),
FriendlyLevel = table.Column<int>(nullable: false)
},
Expand All @@ -79,6 +82,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false)
},
constraints: table =>
Expand All @@ -98,6 +102,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false),
Avatar = table.Column<byte[]>(nullable: true),
Description = table.Column<string>(maxLength: 2000, nullable: true),
Expand Down Expand Up @@ -126,6 +131,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false),
FriendlyName = table.Column<string>(maxLength: 10, nullable: false),
ExternalId = table.Column<int>(nullable: false),
Expand Down Expand Up @@ -168,9 +174,11 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
Name = table.Column<string>(maxLength: 50, nullable: false),
Avatar = table.Column<byte[]>(nullable: true),
Description = table.Column<string>(maxLength: 2000, nullable: true),
ProfileVisibility = table.Column<int>(nullable: false),
SppdName = table.Column<string>(maxLength: 50, nullable: false),
PasswordHash = table.Column<byte[]>(maxLength: 64, nullable: false),
PasswordSalt = table.Column<byte[]>(maxLength: 128, nullable: false),
Expand Down Expand Up @@ -210,6 +218,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
CardId = table.Column<Guid>(nullable: false),
UserId = table.Column<Guid>(nullable: false),
Level = table.Column<int>(nullable: false)
Expand All @@ -231,11 +240,46 @@ protected override void Up(MigrationBuilder migrationBuilder)
onDelete: ReferentialAction.Cascade);
});

migrationBuilder.CreateTable(
name: "TeamMembershipRequest",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
CreatedOnUtc = table.Column<DateTime>(nullable: false),
CreatedById = table.Column<Guid>(nullable: false),
ModifiedOnUtc = table.Column<DateTime>(nullable: false),
ModifiedById = table.Column<Guid>(nullable: false),
IsDeleted = table.Column<bool>(nullable: false),
DeletedOnUtc = table.Column<DateTime>(nullable: true),
DeletedById = table.Column<Guid>(nullable: true),
Version = table.Column<byte[]>(rowVersion: true, nullable: true),
TeamId = table.Column<Guid>(nullable: false),
UserId = table.Column<Guid>(nullable: false),
Comment = table.Column<string>(maxLength: 500, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_TeamMembershipRequest", x => x.Id);
table.ForeignKey(
name: "FK_TeamMembershipRequest_Team_TeamId",
column: x => x.TeamId,
principalTable: "Team",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TeamMembershipRequest_TeamTunerUser_UserId",
column: x => x.UserId,
principalTable: "TeamTunerUser",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});

migrationBuilder.CreateIndex(
name: "IX_Card_ExternalId",
table: "Card",
column: "ExternalId",
unique: true);
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_Card_RarityId",
Expand All @@ -258,20 +302,37 @@ protected override void Up(MigrationBuilder migrationBuilder)
column: "CardId");

migrationBuilder.CreateIndex(
name: "IX_CardLevel_UserId",
name: "IX_CardLevel_UserId_CardId",
table: "CardLevel",
column: "UserId");
columns: new[] { "UserId", "CardId" },
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_Team_FederationId",
table: "Team",
column: "FederationId");

migrationBuilder.CreateIndex(
name: "IX_TeamMembershipRequest_TeamId",
table: "TeamMembershipRequest",
column: "TeamId",
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_TeamMembershipRequest_UserId",
table: "TeamMembershipRequest",
column: "UserId",
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_TeamTunerUser_Email",
table: "TeamTunerUser",
column: "Email",
unique: true);
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_TeamTunerUser_FederationId",
Expand All @@ -282,13 +343,15 @@ protected override void Up(MigrationBuilder migrationBuilder)
name: "IX_TeamTunerUser_Name",
table: "TeamTunerUser",
column: "Name",
unique: true);
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_TeamTunerUser_SppdName",
table: "TeamTunerUser",
column: "SppdName",
unique: true);
unique: true,
filter: "[IsDeleted] = 0");

migrationBuilder.CreateIndex(
name: "IX_TeamTunerUser_TeamId",
Expand All @@ -301,6 +364,9 @@ protected override void Down(MigrationBuilder migrationBuilder)
migrationBuilder.DropTable(
name: "CardLevel");

migrationBuilder.DropTable(
name: "TeamMembershipRequest");

migrationBuilder.DropTable(
name: "Card");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Sppd.TeamTuner.Infrastructure.DataAccess.EF;
using Sppd.TeamTuner.Infrastructure.DataAccess.EF.MsSql;

namespace Sppd.TeamTuner.Infrastructure.DataAccess.EF.Migrations
namespace Sppd.TeamTuner.Infrastructure.DataAccess.EF.MsSql.Migrations
{
[DbContext(typeof(TeamTunerContext))]
partial class TeamTunerContextModelSnapshot : ModelSnapshot
[DbContext(typeof(TeamTunerContextMsSql))]
partial class TeamTunerContextMsSqlModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sppd.TeamTuner.Core\Sppd.TeamTuner.Core.csproj" />
<ProjectReference Include="..\Sppd.TeamTuner.Infrastructure.DataAccess.EF\Sppd.TeamTuner.Infrastructure.DataAccess.EF.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

using Sppd.TeamTuner.Core;
using Sppd.TeamTuner.Core.Services;
using Sppd.TeamTuner.Core.Utils.Extensions;
using Sppd.TeamTuner.Infrastructure.DataAccess.EF.Config;

namespace Sppd.TeamTuner.Infrastructure.DataAccess.EF.MsSql
{
public class StartupRegistrator : IStartupRegistrator
{
private const string PROVIDER_NAME = "MsSql";
private const string ID_PLACEHOLDER = "{id}";

public int Priority => 90;

public void Register(IServiceCollection services)
{
var databaseConfig = services.BuildServiceProvider().GetConfig<DatabaseConfig>();

if (PROVIDER_NAME.Equals(databaseConfig.Provider, StringComparison.InvariantCultureIgnoreCase))
{
// Add a random string if the {id} specifier is contained in the connection string
var dbId = Guid.NewGuid().ToString("n").Substring(0, 8);
databaseConfig.ConnectionString = databaseConfig.ConnectionString.Replace(ID_PLACEHOLDER, dbId);

services.AddDbContext<TeamTunerContextMsSql>(options => options.UseSqlServer(databaseConfig.ConnectionString))
.AddScoped<TeamTunerContext, TeamTunerContextMsSql>()
.AddScoped<IDatabaseService, TeamTunerContextMsSql>();
}
}

public void Configure(IServiceProvider serviceProvider)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;

using Microsoft.EntityFrameworkCore;

using Sppd.TeamTuner.Core.Domain.Interfaces;
using Sppd.TeamTuner.Core.Services;

namespace Sppd.TeamTuner.Infrastructure.DataAccess.EF.MsSql
{
/// <summary>
/// Extends <see cref="TeamTunerContext" /> to allow managing migrations in the project.
/// </summary>
/// <seealso cref="TeamTunerContext" />
internal class TeamTunerContextMsSql : TeamTunerContext
{
public TeamTunerContextMsSql(DbContextOptions options, Lazy<IValidationService> validationService, IEnumerable<Lazy<IEntityMetadataProvider>> entityMetadataProviders)
: base(options, validationService, entityMetadataProviders)
{
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 339ca7f

Please sign in to comment.