diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder.csproj b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder.csproj new file mode 100644 index 0000000..413e6ea --- /dev/null +++ b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder.csproj @@ -0,0 +1,19 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + + + + + diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Program.cs b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Program.cs new file mode 100644 index 0000000..f63a7d5 --- /dev/null +++ b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Program.cs @@ -0,0 +1,58 @@ +using NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder; +using System.CommandLine; +using System.CommandLine.Builder; +using System.CommandLine.Parsing; + +var sourceOption + = new Option( + new[] { "--source", "-s" }, + (argumentResult) => new FileInfo(argumentResult.Tokens[0].Value), + description: "Defines the source .dll to search for migration data" + ); + +var targetOption + = new Option( + new[] { "--target", "-t" }, + (argumentResult) => new DirectoryInfo(argumentResult.Tokens[0].Value), + description: "Defines the directory where the migration should be generated" + ); + +var root = new RootCommand("search dll for DatabaseContext and generate Migration files") + { + sourceOption, + targetOption + }; + +root.SetHandler(Service.Start, sourceOption, targetOption); + +var parser = new CommandLineBuilder(root).UseDefaults().Build(); + +ParseResult parsedArguments; + +if (args is null || args.Length == 0) +{ + Console.Write("> "); + var clr = Console.ReadLine(); + parsedArguments = parser.Parse(clr); +} +else +{ + parsedArguments = parser.Parse(args); +} + +if (parsedArguments.Errors.Count > 0 && parsedArguments.Tokens.Count > 0) +{ + Console.WriteLine($"{parsedArguments.Errors.Count} Errors in the parse process."); + foreach (var error in parsedArguments.Errors) + { + Console.WriteLine(error.Message); + } + + parser.Invoke("-?"); + + return 1; +} +else +{ + return parsedArguments.Invoke(); +} \ No newline at end of file diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Properties/launchSettings.json b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Properties/launchSettings.json new file mode 100644 index 0000000..3c83171 --- /dev/null +++ b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder": { + "commandName": "Project", + "commandLineArgs": "-s \"F:\\Projekte\\Visual 2019\\NonSucking.Framework.Extension\\TestCoreExtension\\bin\\Debug\\net7.0\\TestCoreExtension.dll\" -t \"F:\\Projekte\\Visual 2019\\NonSucking.Framework.Extension\\TestCoreExtension\\Migration\"" + } + } +} \ No newline at end of file diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Service.cs b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Service.cs new file mode 100644 index 0000000..d598431 --- /dev/null +++ b/NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder/Service.cs @@ -0,0 +1,45 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.EntityFrameworkCore; +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using System.Text; +using System.Threading.Tasks; + +namespace NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder; +internal static class Service +{ + public static void Start(FileInfo sourceFile, DirectoryInfo targetDirectory) + { + var context = new AssemblyLoadContext("sourceContext"); + + using var stream = sourceFile.OpenRead(); + + context.LoadFromStream(stream); + + var types + = context + .Assemblies + .SelectMany(x => x.GetTypes()) + .Where(type => !type.IsAbstract && !type.IsInterface && type.IsAssignableTo(typeof(IEntity))) + .Where(type => type.GetCustomAttribute() is null); + + //Todo: create migration class and designer file + //requires implementation of IAutoMigrationTypeProvider + //Add: const Id field of patter Number_name example: 1_Initialized + foreach (var type in types) + { + //add types to designer file put History attribute on it + //example: [History(Migration.Id)] + foreach (var property in type.GetProperties()) + { + + } + } + } +} diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore/DatabaseContext.cs b/NonSucking.Framework.Extension.EntityFrameworkCore/DatabaseContext.cs index 717ea0c..f613bd8 100644 --- a/NonSucking.Framework.Extension.EntityFrameworkCore/DatabaseContext.cs +++ b/NonSucking.Framework.Extension.EntityFrameworkCore/DatabaseContext.cs @@ -11,7 +11,6 @@ namespace NonSucking.Framework.Extension.EntityFrameworkCore { - public abstract class DatabaseContext : DbContext, IAutoMigrationContext { public bool EnableUseLazyLoading { get; set; } = true; @@ -63,31 +62,11 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) base.OnConfiguring(optionsBuilder); } - static Type[] onModelCreatingMethodTypes = new[] { typeof(ModelBuilder) }; protected override void OnModelCreating(ModelBuilder modelBuilder) { if (AddAllEntities) { - - foreach (var type in AssemblyLoadContext - .Default - .Assemblies - .Where(x => string.IsNullOrWhiteSpace(AssemblyRootName) - || x.FullName.Contains(AssemblyRootName)) - .SelectMany(x => x.GetTypes()) - .Where(type => !type.IsAbstract - && !type.IsInterface - && typeof(IEntity).IsAssignableFrom(type)) - .Where(x => x.Namespace is not null && !x.Namespace.Contains("Migration"))) - { - if (modelBuilder.Model.FindEntityType(type) is null) - { - _ = modelBuilder.Model.AddEntityType(type); - } - var method = type.GetMethod(nameof(OnModelCreating), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, onModelCreatingMethodTypes); - if (method is not null) - method.Invoke(null, new[] { modelBuilder }); - } + modelBuilder.BuildCurrent(AssemblyRootName); } base.OnModelCreating(modelBuilder); diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/HistoryAttribute.cs b/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/HistoryAttribute.cs new file mode 100644 index 0000000..887e31a --- /dev/null +++ b/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/HistoryAttribute.cs @@ -0,0 +1,17 @@ +namespace NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false, Inherited = true)] +public class HistoryAttribute : Attribute +{ + /// + /// The version to migrate to + /// + public string Version { get; } + + /// + /// Creates a custom migration config + /// + public HistoryAttribute() + { + } +} diff --git a/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/ModelMigration.cs b/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/ModelMigration.cs index 28b211b..1bb3931 100644 --- a/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/ModelMigration.cs +++ b/NonSucking.Framework.Extension.EntityFrameworkCore/Migrations/ModelMigration.cs @@ -4,19 +4,54 @@ using Microsoft.EntityFrameworkCore.Migrations; using System.Reflection; +using System.Runtime.Loader; namespace NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; public static class ModelMigration { + public static void BuildCurrent(this ModelBuilder modelBuilder, string assemblyRootName) + { + HashSet assemblies = new HashSet(); + foreach (var type in GetEntityTypes(assemblyRootName) + .Where(type => + type.GetCustomAttribute() is null + && type.DeclaringType?.GetCustomAttribute() is null)) + { + if (modelBuilder.Model.FindEntityType(type) is not null) + continue; + + _ = modelBuilder.Model.AddEntityType(type); + assemblies.Add(type.Assembly); + } + foreach (var item in assemblies) + { + modelBuilder.ApplyConfigurationsFromAssembly(item); + } + } + public static void BuildVersion(this ModelBuilder modelBuilder, string version) { + static bool HasCorrectVersion(Type type, string version) + { + var attribute + = type.GetCustomAttribute() + ?? type.DeclaringType?.GetCustomAttribute(); + return attribute is not null + && attribute.Version == version; + } + foreach (var type in GetEntityTypes(null) + .Where(type => HasCorrectVersion(type, version))) + { + if (modelBuilder.Model.FindEntityType(type) is null) + _ = modelBuilder.Model.AddEntityType(type); + } } + public static void BuildVersion(this ModelBuilder modelBuilder, IAutoMigrationTypeProvider typeProvider) { - //TODO: Solution required our table names are property names from the context foreach (var type in typeProvider.GetEntityTypes()) { if (modelBuilder.Model.FindEntityType(type) is null) @@ -43,13 +78,25 @@ public static void SetDowngradeOperations(this MigrationBuilder migrationBuilder migrationBuilder.Operations.AddRange(diff); } + private static IEnumerable GetEntityTypes(string? assemblyRootName) + { + return AssemblyLoadContext + .Default + .Assemblies + .Where(x => string.IsNullOrWhiteSpace(assemblyRootName) + || x.FullName.Contains(assemblyRootName)) + .SelectMany(x => x.GetTypes()) + .Where(type => !type.IsAbstract && !type.IsInterface && type.IsAssignableTo(typeof(IEntity))); + } private static void GetMigrationClasses(Migration migration, out IAutoMigrationContextBuilder providerContextBuilder, out IModel target, out IModel? source) { - providerContextBuilder = DatabaseFactory.DatabaseConfigurators.First().GetEmptyForMigration(); var migrationType = migration.GetType(); var contextAttribute = migrationType.GetCustomAttribute() ?? throw new ArgumentNullException(); - var currentContext = (IAutoMigrationContext)Activator.CreateInstance(contextAttribute.ContextType)!; + var builderFromConfig = DatabaseFactory.DatabaseConfigurators.FirstOrDefault()?.GetEmptyForMigration(); + + providerContextBuilder = builderFromConfig ?? (IAutoMigrationContextBuilder)Activator.CreateInstance(contextAttribute.ContextType)!; + var currentContext = (IAutoMigrationContext)Activator.CreateInstance(contextAttribute.ContextType)!; var targetBuilder = providerContextBuilder.CreateBuilder(); if (migration is IAutoMigrationTypeProvider autoTypeProvider) @@ -58,14 +105,16 @@ private static void GetMigrationClasses(Migration migration, out IAutoMigrationC } else { - var idAttribute = migrationType.GetCustomAttribute() ?? - throw new ArgumentNullException(); + var idAttribute + = migrationType.GetCustomAttribute() + ?? throw new ArgumentNullException(); targetBuilder.BuildVersion(idAttribute.Id); } target = providerContextBuilder.FinalizeModel((IModel)targetBuilder.Model); source = null; + if (currentContext.FindLastMigration(contextAttribute.ContextType, out var lastMigration, out var lastMigrationId)) { var sourceBuilder = providerContextBuilder.CreateBuilder(); diff --git a/NonSucking.Framework.Extension.sln b/NonSucking.Framework.Extension.sln index 863aa75..55dc9a3 100644 --- a/NonSucking.Framework.Extension.sln +++ b/NonSucking.Framework.Extension.sln @@ -35,6 +35,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NonSucking.Framework.Extens EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NonSucking.Framework.Extension.Database.PostgreSQL", "EntityFrameworkExtension\NonSucking.Framework.Extension.Database.PostgreSQL\NonSucking.Framework.Extension.Database.PostgreSQL.csproj", "{3B88FE46-6E96-4597-AC05-60984F3B4FD0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder", "NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder\NonSucking.Framework.Extension.EntityFrameworkCore.MigrationBuilder.csproj", "{93086D2B-A9CC-461C-A9C7-6EDEA0635753}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestCoreExtension", "TestCoreExtension\TestCoreExtension.csproj", "{143FA061-260E-4EAB-A208-725342061E81}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -101,6 +105,14 @@ Global {3B88FE46-6E96-4597-AC05-60984F3B4FD0}.Debug|Any CPU.Build.0 = Debug|Any CPU {3B88FE46-6E96-4597-AC05-60984F3B4FD0}.Release|Any CPU.ActiveCfg = Release|Any CPU {3B88FE46-6E96-4597-AC05-60984F3B4FD0}.Release|Any CPU.Build.0 = Release|Any CPU + {93086D2B-A9CC-461C-A9C7-6EDEA0635753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {93086D2B-A9CC-461C-A9C7-6EDEA0635753}.Debug|Any CPU.Build.0 = Debug|Any CPU + {93086D2B-A9CC-461C-A9C7-6EDEA0635753}.Release|Any CPU.ActiveCfg = Release|Any CPU + {93086D2B-A9CC-461C-A9C7-6EDEA0635753}.Release|Any CPU.Build.0 = Release|Any CPU + {143FA061-260E-4EAB-A208-725342061E81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {143FA061-260E-4EAB-A208-725342061E81}.Debug|Any CPU.Build.0 = Debug|Any CPU + {143FA061-260E-4EAB-A208-725342061E81}.Release|Any CPU.ActiveCfg = Release|Any CPU + {143FA061-260E-4EAB-A208-725342061E81}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TestCoreExtension/Bothamster/BaseDatabaseContext.cs b/TestCoreExtension/Bothamster/BaseDatabaseContext.cs new file mode 100644 index 0000000..6bbe0f0 --- /dev/null +++ b/TestCoreExtension/Bothamster/BaseDatabaseContext.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; + +using NonSucking.Framework.Extension.EntityFrameworkCore; + +namespace TestCoreExtension.Bothamster; + +public class BaseDatabaseContext : DatabaseContext +{ + public BaseDatabaseContext() + { + } + + public BaseDatabaseContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite("Filename =Test.db"); + + base.OnConfiguring(optionsBuilder); + } +} diff --git a/TestCoreExtension/Bothamster/Group.cs b/TestCoreExtension/Bothamster/Group.cs new file mode 100644 index 0000000..ce9d0a8 --- /dev/null +++ b/TestCoreExtension/Bothamster/Group.cs @@ -0,0 +1,24 @@ + + +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension.Bothamster; + +[Table("Groups")] +public class Group : IdEntity +{ + public bool IsDefault { get; set; } + public string Name { get; set; } + + [InverseProperty(nameof(User.Groups))] + public virtual List Users { get; set; } = new List(); + [InverseProperty(nameof(PlattformUser.Groups))] + public virtual List PlattformUsers { get; set; } = new List(); + [InverseProperty(nameof(Right.Groups))] + public virtual List Rights { get; set; } = new List(); + + public Group Clone() + { + return new Group { Id = Id, IsDefault = IsDefault, Name = Name, Users = Users.ToList(), PlattformUsers = PlattformUsers.ToList(), Rights = Rights.ToList() }; + } +} diff --git a/TestCoreExtension/Bothamster/IdEntity.cs b/TestCoreExtension/Bothamster/IdEntity.cs new file mode 100644 index 0000000..9799759 --- /dev/null +++ b/TestCoreExtension/Bothamster/IdEntity.cs @@ -0,0 +1,38 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension.Bothamster +{ + public abstract class IdEntity : IEquatable?> + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public T Id { get; set; } + + public override bool Equals(object? obj) + { + return Equals(obj as IdEntity); + } + + public bool Equals(IdEntity? other) + { + return other is not null && + EqualityComparer.Default.Equals(Id, other.Id); + } + + public override int GetHashCode() + { + return HashCode.Combine(Id); + } + + public static bool operator ==(IdEntity? left, IdEntity? right) + { + return EqualityComparer>.Default.Equals(left, right); + } + + public static bool operator !=(IdEntity? left, IdEntity? right) + { + return !(left == right); + } + } +} diff --git a/TestCoreExtension/Bothamster/Migrations/RightsContextMigration001.Designer.cs b/TestCoreExtension/Bothamster/Migrations/RightsContextMigration001.Designer.cs new file mode 100644 index 0000000..1450ad6 --- /dev/null +++ b/TestCoreExtension/Bothamster/Migrations/RightsContextMigration001.Designer.cs @@ -0,0 +1,83 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Migrations; + +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using TestCoreExtension.Bothamster; + +namespace BotMaster.RightsManagement.Migrations; + +#nullable enable +public partial class RightsContextMigration001 : IAutoMigrationTypeProvider +{ + //2022_10_23-20_39_01-RightsDbContext-InitialMigration + //2022_10_23-20_39_01-RightsDbContext-InitialMigration + public const string Id = $"2022_10_23-20_39_01-{nameof(RightsDbContext)}-InitialMigration"; + public IReadOnlyList GetEntityTypes() + { + return new[] + { + typeof(Group), + typeof(User), + typeof(PlattformUser), + typeof(Right), + + }; + } + + [Table("Groups")] + public class Group : IdEntity + { + public bool IsDefault { get; set; } + public string Name { get; set; } + + public virtual ICollection Users { get; set; } = new List(); + public virtual ICollection PlattformUsers { get; set; } = new List(); + public virtual ICollection Rights { get; set; } = new List(); + } + [Table("Users")] + public class User : IdEntity + { + public string DisplayName { get; set; } + + public virtual ICollection PlatformIdentities { get; set; } = new List(); + public virtual ICollection Groups { get; set; } = new List(); + public virtual ICollection Rights { get; set; } = new List(); + + } + [Table("PlattformUsers")] + public class PlattformUser : IdEntity + { + + + [Required] + public string Platform { get; set; } + [Required] + public string Name { get; set; } + [Required] + public string PlattformUserId { get; set; } + + public virtual User? User { get; set; } + public virtual ICollection Rights { get; set; } = new List(); + public virtual ICollection Groups { get; set; } = new List(); + } + + [Table("Rights")] + public class Right : IdEntity + { + public string Name { get; set; } + + public virtual ICollection PlattformUsers { get; set; } = new List(); + public virtual ICollection Groups { get; set; } = new List(); + public virtual ICollection Users { get; set; } = new List(); + } +} diff --git a/TestCoreExtension/Bothamster/Migrations/RightsContextMigration001.cs b/TestCoreExtension/Bothamster/Migrations/RightsContextMigration001.cs new file mode 100644 index 0000000..f164130 --- /dev/null +++ b/TestCoreExtension/Bothamster/Migrations/RightsContextMigration001.cs @@ -0,0 +1,19 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +using TestCoreExtension.Bothamster; +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +namespace BotMaster.RightsManagement.Migrations; + +[Migration(Id)] +[DbContext(typeof(RightsDbContext))] +public partial class RightsContextMigration001 : Migration +{ + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.SetUpgradeOperations(this); + } +} diff --git a/TestCoreExtension/Bothamster/Migrations/UserConnectionContextMigration001.Designer.cs b/TestCoreExtension/Bothamster/Migrations/UserConnectionContextMigration001.Designer.cs new file mode 100644 index 0000000..ff35def --- /dev/null +++ b/TestCoreExtension/Bothamster/Migrations/UserConnectionContextMigration001.Designer.cs @@ -0,0 +1,43 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Migrations; + +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using TestCoreExtension.Bothamster; + +namespace BotMaster.RightsManagement.Migrations; + + +#nullable enable +public partial class UserConnectionContextMigration001 : IAutoMigrationTypeProvider +{ + public const string Id = $"2022_10_23-20_39_01-{nameof(UserConnectionContext)}-InitialMigration"; + public IReadOnlyList GetEntityTypes() + { + return new[] + { + typeof(UserConnection), + }; + } + + [Table("UserConnections")] + public class UserConnection : IdEntity + { + public string ConnectionCode { get; set; } + public DateTime ValidUntil { get; set; } + public bool Connected { get; set; } + + public int PlattformUserId { get; set; } + + } + +} diff --git a/TestCoreExtension/Bothamster/Migrations/UserConnectionContextMigration001.cs b/TestCoreExtension/Bothamster/Migrations/UserConnectionContextMigration001.cs new file mode 100644 index 0000000..4c2f71e --- /dev/null +++ b/TestCoreExtension/Bothamster/Migrations/UserConnectionContextMigration001.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +using TestCoreExtension.Bothamster; + +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; +namespace BotMaster.RightsManagement.Migrations; + +[Migration(Id)] +[DbContext(typeof(UserConnectionContext))] +public partial class UserConnectionContextMigration001 : Migration +{ + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.SetUpgradeOperations(this); + migrationBuilder.AddForeignKey("FK_UserConnections_PlattformUsers_PlattformUserId", "UserConnections", + "PlattformUserId", "PlattformUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade); + + } +} diff --git a/TestCoreExtension/Bothamster/PlattformUser.cs b/TestCoreExtension/Bothamster/PlattformUser.cs new file mode 100644 index 0000000..bbbfbf8 --- /dev/null +++ b/TestCoreExtension/Bothamster/PlattformUser.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension.Bothamster; + +[Table("PlattformUsers")] +public class PlattformUser : IdEntity +{ + [Required] + public string Platform { get; set; } + [Required] + public string Name { get; set; } + [Required] + public string PlattformUserId { get; set; } + + public virtual User? User { get; set; } + + [InverseProperty(nameof(Right.PlattformUsers))] + public virtual ICollection Rights { get; set; } = new List(); + + [InverseProperty(nameof(Group.PlattformUsers))] + public virtual ICollection Groups { get; set; } = new List(); + + public PlattformUser Clone() + { + return new PlattformUser { Id = Id, Platform = Platform, Name = Name, PlattformUserId = PlattformUserId, User = User, Rights = Rights.ToList(), Groups = Groups.ToList() }; + } +} diff --git a/TestCoreExtension/Bothamster/Right.cs b/TestCoreExtension/Bothamster/Right.cs new file mode 100644 index 0000000..39da2cf --- /dev/null +++ b/TestCoreExtension/Bothamster/Right.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension.Bothamster; + +[Table("Rights")] +public class Right : IdEntity +{ + public string Name { get; set; } + + [InverseProperty(nameof(PlattformUser.Rights))] + public virtual List PlattformUsers { get; set; } = new List(); + [InverseProperty(nameof(Group.Rights))] + public virtual List Groups { get; set; } = new List(); + [InverseProperty(nameof(User.Rights))] + public virtual List Users { get; set; } = new List(); + + public Right Clone() + { + return new Right { Name = Name, Id = Id, Groups = Groups.ToList(), PlattformUsers = PlattformUsers.ToList(), Users = Users.ToList() }; + } +} \ No newline at end of file diff --git a/TestCoreExtension/Bothamster/RightsContext.cs b/TestCoreExtension/Bothamster/RightsContext.cs new file mode 100644 index 0000000..4b1081f --- /dev/null +++ b/TestCoreExtension/Bothamster/RightsContext.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; + +namespace TestCoreExtension.Bothamster; +public class RightsDbContext : BaseDatabaseContext +{ + //public DbSet TelegramUsers => Set(); + public DbSet Groups => Set(); + public DbSet Users => Set(); + public DbSet PlattformUsers => Set(); + public DbSet Rights => Set(); + + public RightsDbContext() : base() + { + } + + public RightsDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } +} diff --git a/TestCoreExtension/Bothamster/User.cs b/TestCoreExtension/Bothamster/User.cs new file mode 100644 index 0000000..085c91e --- /dev/null +++ b/TestCoreExtension/Bothamster/User.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension.Bothamster; + +[Table("Users")] +public class User : IdEntity +{ + public string DisplayName { get; set; } + + [InverseProperty(nameof(PlattformUser.User))] + public virtual List PlatformIdentities { get; set; } = new List(); + [InverseProperty(nameof(Group.Users))] + public virtual List Groups { get; set; } = new List(); + [InverseProperty(nameof(Right.Users))] + public virtual List Rights { get; set; } = new List(); + + public User Clone() + { + return new User() + { + DisplayName = DisplayName, + PlatformIdentities = PlatformIdentities.ToList(), + Groups = Groups.ToList(), + Rights = Rights.ToList(), + Id = Id + }; + } +} diff --git a/TestCoreExtension/Bothamster/UserConnection.cs b/TestCoreExtension/Bothamster/UserConnection.cs new file mode 100644 index 0000000..6225d0f --- /dev/null +++ b/TestCoreExtension/Bothamster/UserConnection.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension.Bothamster; + +[Table("UserConnections")] +public class UserConnection : IdEntity +{ + public string ConnectionCode { get; set; } + public DateTime ValidUntil { get; set; } + public bool Connected { get; set; } + + public int PlattformUserId { get; set; } + + [ForeignKey(nameof(PlattformUserId))] + public virtual PlattformUser? PlattformUser { get; set; } + + public UserConnection Clone() + { + return new() + { + Connected = Connected, + ConnectionCode = ConnectionCode, + ValidUntil = ValidUntil, + PlattformUserId = PlattformUserId, + PlattformUser = PlattformUser?.Clone() + }; + } +} diff --git a/TestCoreExtension/Bothamster/UserConnectionContext.cs b/TestCoreExtension/Bothamster/UserConnectionContext.cs new file mode 100644 index 0000000..7d7155a --- /dev/null +++ b/TestCoreExtension/Bothamster/UserConnectionContext.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; + +namespace TestCoreExtension.Bothamster; + +public class UserConnectionContext : BaseDatabaseContext +{ + public DbSet UserConnections => Set(); + public DbSet PlattformUsers => Set(); + public DbSet Users => Set(); + + public UserConnectionContext() + { + } + + public UserConnectionContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } +} diff --git a/TestCoreExtension/Program.cs b/TestCoreExtension/Program.cs new file mode 100644 index 0000000..ed2a848 --- /dev/null +++ b/TestCoreExtension/Program.cs @@ -0,0 +1,52 @@ +// See https://aka.ms/new-console-template for more information +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; + +using NonSucking.Framework.Extension.Database.Sqlite; +using NonSucking.Framework.Extension.EntityFrameworkCore; + +using TestCoreExtension.Bothamster; + +DatabaseFactory.DatabaseConfigurators.Add(new SqLiteConfigurator()); + +using (var ctx = new RightsDbContext()) + ctx.Migrate(); + +using (var ctx = new UserConnectionContext()) + ctx.Migrate(); + +var b = typeof(A.B); +; +public class A +{ + public class B + { + + } +} + + +class DbContext2 : DatabaseContext +{ + public DbSet Examples { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite("Filename =Test.db"); + base.OnConfiguring(optionsBuilder); + } +} + +public class Example : IEntity +{ + public int Id { get; set; } + + public string Name { get; set; } + + public int Id2 { get; set; } +} \ No newline at end of file diff --git a/TestCoreExtension/Test - Kopie.db b/TestCoreExtension/Test - Kopie.db new file mode 100644 index 0000000..d753674 Binary files /dev/null and b/TestCoreExtension/Test - Kopie.db differ diff --git a/TestCoreExtension/Test.db b/TestCoreExtension/Test.db new file mode 100644 index 0000000..d753674 Binary files /dev/null and b/TestCoreExtension/Test.db differ diff --git a/TestCoreExtension/TestCoreExtension.csproj b/TestCoreExtension/TestCoreExtension.csproj new file mode 100644 index 0000000..323afbe --- /dev/null +++ b/TestCoreExtension/TestCoreExtension.csproj @@ -0,0 +1,26 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + + + + + + + + Always + + + + diff --git a/TestCoreExtension/TestMigration002.cs b/TestCoreExtension/TestMigration002.cs new file mode 100644 index 0000000..ad1b35f --- /dev/null +++ b/TestCoreExtension/TestMigration002.cs @@ -0,0 +1,44 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +using NonSucking.Framework.Extension.EntityFrameworkCore; +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +using System.ComponentModel.DataAnnotations.Schema; + +namespace TestCoreExtension; + +//[Migration(Id)] +[DbContext(typeof(DbContext2))] +public partial class TestMigration002 : Migration +{ + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.SetUpgradeOperations(this); + + } +} +[History] +public partial class TestMigration002 : IAutoMigrationTypeProvider +{ + public const string Id = $"2022_10_23-20_39_02-{nameof(DbContext2)}-InitialMigration"; + public IReadOnlyList GetEntityTypes() + { + return new[] + { + typeof(Example), + }; + } + + [Table("Example")] + private class Example : IEntity + { + public int Id { get; set; } + + public string Name { get; set; } + public int Id2 { get; set; } + } + +} diff --git a/TestCoreExtension/UserConnectionContextMigration001.Designer.cs b/TestCoreExtension/UserConnectionContextMigration001.Designer.cs new file mode 100644 index 0000000..0d36af4 --- /dev/null +++ b/TestCoreExtension/UserConnectionContextMigration001.Designer.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Migrations; + +using NonSucking.Framework.Extension.EntityFrameworkCore; +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestCoreExtension; + + +#nullable enable +[History] +public partial class UserConnectionContextMigration001 : IAutoMigrationTypeProvider +{ + public const string Id = $"2022_10_23-20_39_01-{nameof(DbContext2)}-InitialMigration"; + public IReadOnlyList GetEntityTypes() + { + return new[] + { + typeof(Example), + }; + } + + [Table("Example")] + private class Example : IEntity + { + public int Id { get; set; } + + public string Name { get; set; } + } + +} diff --git a/TestCoreExtension/UserConnectionContextMigration001.cs b/TestCoreExtension/UserConnectionContextMigration001.cs new file mode 100644 index 0000000..19d27e1 --- /dev/null +++ b/TestCoreExtension/UserConnectionContextMigration001.cs @@ -0,0 +1,19 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +using NonSucking.Framework.Extension.EntityFrameworkCore.Migrations; + +namespace TestCoreExtension; + +//[Migration(Id)] +[DbContext(typeof(DbContext2))] +public partial class UserConnectionContextMigration001 : Migration +{ + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.SetUpgradeOperations(this); + + } +}