Compare commits

...

4 Commits

18 changed files with 420 additions and 808 deletions

View File

@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Linq;
using LinqToDB.Configuration;
namespace DataModels
{
public class ConnectionStringSettings : IConnectionStringSettings
{
public string ConnectionString { get; set; }
public string Name { get; set; }
public string ProviderName { get; set; }
public bool IsGlobal => false;
}
public class MySettings : ILinqToDBSettings
{
public IEnumerable<IDataProviderSettings> DataProviders => Enumerable.Empty<IDataProviderSettings>();
public string DefaultConfiguration => "MySqlServer";
public string DefaultDataProvider => "MySqlServer";
public IEnumerable<IConnectionStringSettings> ConnectionStrings
{
get
{
yield return
new ConnectionStringSettings
{
Name = "Northwind",
ProviderName = "MySqlServer",
ConnectionString = @"Server=srvbo;Database=UserService;Uid=UserDbAdmin;Pwd=12345678;"
};
}
}
}
}

View File

@ -1,78 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using UserService.Infrastructure.DataModels;
namespace UserService.DatabaseLayer.DataModels
{
public static class ModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
if (modelBuilder == null) throw new ArgumentNullException(nameof(modelBuilder));
var groups = new OrganizationUnit { CommonName = "Groups", Id = Guid.NewGuid() };
var users = new OrganizationUnit { CommonName = "Users", Id = Guid.NewGuid() };
var germany = new OrganizationUnit { CommonName = "Germany", Id = Guid.NewGuid(), ParentId = users.Id };
var usa = new OrganizationUnit { CommonName = "USA", Id = Guid.NewGuid(), ParentId = users.Id };
var arizona = new OrganizationUnit { CommonName = "Arizona", Id = Guid.NewGuid(), ParentId = usa.Id };
var france = new OrganizationUnit { CommonName = "France", Id = Guid.NewGuid(), ParentId = users.Id };
modelBuilder.Entity<OrganizationUnit>().HasData(users, groups, germany, usa, arizona, france);
var user = new User { CommonName = Environment.UserName, IsActive = true, Id = Guid.NewGuid(), ParentId = users.Id };
modelBuilder.Entity<User>().HasData(user);
var secGroup = new SecurityGroup { CommonName = "Global Admin", Id = Guid.NewGuid(), ParentId = groups.Id };
modelBuilder.Entity<SecurityGroup>().HasData(secGroup);
modelBuilder.Entity<MembersMember>()
.HasData(new MembersMember { MemberId = secGroup.Id, AttachedMemberId = user.Id });
}
public static void CreateRelations(this ModelBuilder modelBuilder)
{
if (modelBuilder == null) throw new ArgumentNullException(nameof(modelBuilder));
modelBuilder.Entity<MembersMember>()
.HasKey(bc => new { bc.MemberId, bc.AttachedMemberId });
modelBuilder.Entity<MembersMember>()
.HasOne(bc => bc.AttachedMember)
.WithMany(b => b!.MemberOf)
.HasForeignKey(bc => bc.AttachedMemberId);
modelBuilder.Entity<MembersMember>()
.HasOne(bc => bc.Member)
.WithMany(c => c!.Members)
.HasForeignKey(bc => bc.MemberId);
modelBuilder.Entity<Node>()
.HasMany(c => c.Children)
.WithOne(e => e.Parent!)
.HasForeignKey(bc => bc.ParentId);
}
}
public static class UserExtensions
{
public static IEnumerable<SecurityGroup> GetSecurityGroups(this User user)
{
if (user == null) throw new ArgumentNullException(nameof(user));
foreach (var userMember in user.MemberOf)
{
if (userMember.Member is SecurityGroup securityGroup)
{
yield return securityGroup;
}
}
}
}
public static class SecurityGroupExtensions
{
public static IEnumerable<Member> GetAttachedMembers(this SecurityGroup securityGroup)
{
if (securityGroup == null) throw new ArgumentNullException(nameof(securityGroup));
foreach (var userMember in securityGroup.Members)
{
if (userMember.AttachedMember is null) continue;
yield return userMember.AttachedMember;
}
}
}
}

View File

@ -0,0 +1,219 @@
//---------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by T4Model template for T4 (https://github.com/linq2db/linq2db).
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//---------------------------------------------------------------------------------------------------
#pragma warning disable 1591
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using LinqToDB;
using LinqToDB.Mapping;
namespace DataModels
{
/// <summary>
/// Database : UserService
/// Data Source : srvbo
/// Server Version : 5.5.5-10.3.22-MariaDB-1ubuntu1
/// </summary>
public partial class UserServiceDB : LinqToDB.Data.DataConnection
{
public ITable<Member> Members { get { return this.GetTable<Member>(); } }
public ITable<MembersMember> MembersMembers { get { return this.GetTable<MembersMember>(); } }
public ITable<Node> Nodes { get { return this.GetTable<Node>(); } }
public ITable<OrganizationUnit> OrganizationUnits { get { return this.GetTable<OrganizationUnit>(); } }
public ITable<SecurityGroup> SecurityGroups { get { return this.GetTable<SecurityGroup>(); } }
public ITable<User> Users { get { return this.GetTable<User>(); } }
public UserServiceDB()
{
InitDataContext();
InitMappingSchema();
}
public UserServiceDB(string configuration)
: base(configuration)
{
InitDataContext();
InitMappingSchema();
}
partial void InitDataContext ();
partial void InitMappingSchema();
}
[Table("Members")]
public partial class Member
{
[Column, NotNull] public int Id { get; set; } // int(11)
#region Associations
/// <summary>
/// MembersMember_ibfk_2_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="AttachedMemberId", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<MembersMember> MembersMemberibfks { get; set; } = null!;
/// <summary>
/// Members_ibfk_2
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="Members_ibfk_2", BackReferenceName="Membersibfks")]
public Node Node { get; set; } = null!;
/// <summary>
/// SecurityGroups_ibfk_2_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<SecurityGroup> SecurityGroupsibfks { get; set; } = null!;
/// <summary>
/// Users_ibfk_2_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<User> Usersibfks { get; set; } = null!;
#endregion
}
[Table("MembersMember")]
public partial class MembersMember
{
[PrimaryKey(1), NotNull] public int MemberId { get; set; } // int(11)
[PrimaryKey(2), NotNull] public int AttachedMemberId { get; set; } // int(11)
#region Associations
/// <summary>
/// MembersMember_ibfk_2
/// </summary>
[Association(ThisKey="AttachedMemberId", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="MembersMember_ibfk_2", BackReferenceName="MembersMemberibfks")]
public Member AttachedMember { get; set; } = null!;
/// <summary>
/// MembersMember_ibfk_3
/// </summary>
[Association(ThisKey="MemberId", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="MembersMember_ibfk_3", BackReferenceName="MembersMemberibfks")]
public SecurityGroup Member { get; set; } = null!;
#endregion
}
[Table("Nodes")]
public partial class Node
{
[PrimaryKey, Identity] public int Id { get; set; } // int(11)
[Column, NotNull ] public string CommonName { get; set; } = null!; // text
#region Associations
/// <summary>
/// Members_ibfk_2_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<Member> Membersibfks { get; set; } = null!;
/// <summary>
/// OrganizationUnits_ibfk_2_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<OrganizationUnit> OrganizationUnitsibfks { get; set; } = null!;
#endregion
}
[Table("OrganizationUnits")]
public partial class OrganizationUnit
{
[Column, NotNull ] public int Id { get; set; } // int(11)
[Column, Nullable] public int? ManagerId { get; set; } // int(11)
[Column, Nullable] public int? ParentId { get; set; } // int(11)
#region Associations
/// <summary>
/// OrganizationUnits_ibfk_3_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="ParentId", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<OrganizationUnit> Ibfks { get; set; } = null!;
/// <summary>
/// OrganizationUnits_ibfk_2
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="OrganizationUnits_ibfk_2", BackReferenceName="OrganizationUnitsibfks")]
public Node Node { get; set; } = null!;
/// <summary>
/// OrganizationUnits_ibfk_3
/// </summary>
[Association(ThisKey="ParentId", OtherKey="Id", CanBeNull=true, Relationship=Relationship.ManyToOne, KeyName="OrganizationUnits_ibfk_3", BackReferenceName="Ibfks")]
public OrganizationUnit? Parent { get; set; }
#endregion
}
[Table("SecurityGroups")]
public partial class SecurityGroup
{
[Column, NotNull] public int Id { get; set; } // int(11)
#region Associations
/// <summary>
/// SecurityGroups_ibfk_2
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="SecurityGroups_ibfk_2", BackReferenceName="SecurityGroupsibfks")]
public Member Member { get; set; } = null!;
/// <summary>
/// MembersMember_ibfk_3_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="MemberId", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<MembersMember> MembersMemberibfks { get; set; } = null!;
#endregion
}
[Table("Users")]
public partial class User
{
[Column, NotNull ] public int Id { get; set; } // int(11)
[Column, Nullable] public string? FirstName { get; set; } // text
[Column, Nullable] public string? LastName { get; set; } // text
[Column, NotNull ] public bool IsActive { get; set; } // bit(1)
#region Associations
/// <summary>
/// Users_ibfk_2
/// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="Users_ibfk_2", BackReferenceName="Usersibfks")]
public Member Member { get; set; } = null!;
#endregion
}
public static partial class TableExtensions
{
public static MembersMember Find(this ITable<MembersMember> table, int MemberId, int AttachedMemberId)
{
return table.FirstOrDefault(t =>
t.MemberId == MemberId &&
t.AttachedMemberId == AttachedMemberId);
}
public static Node Find(this ITable<Node> table, int Id)
{
return table.FirstOrDefault(t =>
t.Id == Id);
}
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,19 @@
<#@ template language="C#" debug="True" hostSpecific="True" #>
<#@ output extension=".generated.cs" #>
<#@ include file="$(LinqToDBT4MySqlTemplatesDirectory)LinqToDB.MySql.Tools.ttinclude" #>
<#@ include file="$(LinqToDBT4MySqlTemplatesDirectory)PluralizationService.ttinclude" #>
<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.MySql.Tools.ttinclude" #>
<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #>
<#
NamespaceName = "DataModels";
// to configure GetSchemaOptions properties, add them here, before load metadata call
LoadMySqlMetadata("srvbo", "UserService", "UserDbAdmin", "12345678");
// LoadMySqlMetadata(string connectionString);
// to adjust loaded database model before generation, add your code here, after load metadata, but before GenerateModel() call
EnableNullableReferenceTypes = true;
GenerateModel();
#>

View File

@ -1,23 +0,0 @@
using Microsoft.EntityFrameworkCore;
using UserService.Infrastructure.DataModels;
namespace UserService.DatabaseLayer.DataModels
{
public class UserServiceDbContext : DbContext
{
public DbSet<User> Users { get; set; } = null!;
public DbSet<SecurityGroup> SecurityGroups { get; set; } = null!;
public DbSet<MembersMember> UserMembers { get; set; } = null!;
public DbSet<OrganizationUnit> OrganizationUnits { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite(@"Data Source=C:\Users\holger\Desktop\UserService\UserService.db");
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.CreateRelations();
modelBuilder.Seed();
}
}
}

View File

@ -1,201 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using UserService.DatabaseLayer.DataModels;
namespace UserService.DatabaseLayer.Migrations
{
[DbContext(typeof(UserServiceDbContext))]
[Migration("20200906191545_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.7");
modelBuilder.Entity("UserService.Infrastructure.DataModels.MembersMember", b =>
{
b.Property<Guid>("MemberId")
.HasColumnType("TEXT");
b.Property<Guid>("AttachedMemberId")
.HasColumnType("TEXT");
b.HasKey("MemberId", "AttachedMemberId");
b.HasIndex("AttachedMemberId");
b.ToTable("UserMembers");
b.HasData(
new
{
MemberId = new Guid("a830a548-8b92-4a95-aa8e-c71ae814c6a3"),
AttachedMemberId = new Guid("fd9f5d95-0898-47d4-8d25-6956077ba269")
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("CommonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("Discriminator")
.IsRequired()
.HasColumnType("TEXT");
b.Property<Guid?>("ParentId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("Node");
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.Member", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
b.HasDiscriminator().HasValue("Member");
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
b.Property<Guid?>("ManagerId")
.HasColumnType("TEXT");
b.HasIndex("ManagerId");
b.HasDiscriminator().HasValue("OrganizationUnit");
b.HasData(
new
{
Id = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"),
CommonName = "Users"
},
new
{
Id = new Guid("c94f4749-b7c7-418d-8c10-bc4253c4b913"),
CommonName = "Groups"
},
new
{
Id = new Guid("c743fff4-9bdf-45a4-b4c9-391f6fc46433"),
CommonName = "Germany",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551")
},
new
{
Id = new Guid("cecbf557-59cc-475c-b136-02da39aa4911"),
CommonName = "USA",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551")
},
new
{
Id = new Guid("89e1d70e-da3d-4cc9-81f1-a2fa76a6d33b"),
CommonName = "Arizona",
ParentId = new Guid("cecbf557-59cc-475c-b136-02da39aa4911")
},
new
{
Id = new Guid("97ad8c82-c5ea-4de1-a474-bf25418a9533"),
CommonName = "France",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551")
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.SecurityGroup", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
b.HasDiscriminator().HasValue("SecurityGroup");
b.HasData(
new
{
Id = new Guid("a830a548-8b92-4a95-aa8e-c71ae814c6a3"),
CommonName = "Global Admin",
ParentId = new Guid("c94f4749-b7c7-418d-8c10-bc4253c4b913")
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.User", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
b.Property<string>("EMail")
.HasColumnType("TEXT");
b.Property<string>("FirstName")
.HasColumnType("TEXT");
b.Property<bool>("IsActive")
.HasColumnType("INTEGER");
b.Property<string>("LastName")
.HasColumnType("TEXT");
b.HasDiscriminator().HasValue("User");
b.HasData(
new
{
Id = new Guid("fd9f5d95-0898-47d4-8d25-6956077ba269"),
CommonName = "holger",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"),
IsActive = true
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.MembersMember", b =>
{
b.HasOne("UserService.Infrastructure.DataModels.Member", "AttachedMember")
.WithMany("MemberOf")
.HasForeignKey("AttachedMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UserService.Infrastructure.DataModels.Member", "Member")
.WithMany("Members")
.HasForeignKey("MemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
{
b.HasOne("UserService.Infrastructure.DataModels.Node", "Parent")
.WithMany("Children")
.HasForeignKey("ParentId");
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
{
b.HasOne("UserService.Infrastructure.DataModels.Member", "Manager")
.WithMany()
.HasForeignKey("ManagerId");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,136 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace UserService.DatabaseLayer.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Node",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
CommonName = table.Column<string>(nullable: false),
Description = table.Column<string>(nullable: true),
ParentId = table.Column<Guid>(nullable: true),
Discriminator = table.Column<string>(nullable: false),
FirstName = table.Column<string>(nullable: true),
LastName = table.Column<string>(nullable: true),
IsActive = table.Column<bool>(nullable: true),
EMail = table.Column<string>(nullable: true),
ManagerId = table.Column<Guid>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Node", x => x.Id);
table.ForeignKey(
name: "FK_Node_Node_ParentId",
column: x => x.ParentId,
principalTable: "Node",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Node_Node_ManagerId",
column: x => x.ManagerId,
principalTable: "Node",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "UserMembers",
columns: table => new
{
MemberId = table.Column<Guid>(nullable: false),
AttachedMemberId = table.Column<Guid>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserMembers", x => new { x.MemberId, x.AttachedMemberId });
table.ForeignKey(
name: "FK_UserMembers_Node_AttachedMemberId",
column: x => x.AttachedMemberId,
principalTable: "Node",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_UserMembers_Node_MemberId",
column: x => x.MemberId,
principalTable: "Node",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
values: new object[] { new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"), "Users", null, "OrganizationUnit", null, null });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
values: new object[] { new Guid("c94f4749-b7c7-418d-8c10-bc4253c4b913"), "Groups", null, "OrganizationUnit", null, null });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
values: new object[] { new Guid("c743fff4-9bdf-45a4-b4c9-391f6fc46433"), "Germany", null, "OrganizationUnit", new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"), null });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
values: new object[] { new Guid("cecbf557-59cc-475c-b136-02da39aa4911"), "USA", null, "OrganizationUnit", new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"), null });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
values: new object[] { new Guid("97ad8c82-c5ea-4de1-a474-bf25418a9533"), "France", null, "OrganizationUnit", new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"), null });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail", "FirstName", "IsActive", "LastName" },
values: new object[] { new Guid("fd9f5d95-0898-47d4-8d25-6956077ba269"), "holger", null, "User", new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"), null, null, true, null });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId" },
values: new object[] { new Guid("a830a548-8b92-4a95-aa8e-c71ae814c6a3"), "Global Admin", null, "SecurityGroup", new Guid("c94f4749-b7c7-418d-8c10-bc4253c4b913") });
migrationBuilder.InsertData(
table: "Node",
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "ManagerId" },
values: new object[] { new Guid("89e1d70e-da3d-4cc9-81f1-a2fa76a6d33b"), "Arizona", null, "OrganizationUnit", new Guid("cecbf557-59cc-475c-b136-02da39aa4911"), null });
migrationBuilder.InsertData(
table: "UserMembers",
columns: new[] { "MemberId", "AttachedMemberId" },
values: new object[] { new Guid("a830a548-8b92-4a95-aa8e-c71ae814c6a3"), new Guid("fd9f5d95-0898-47d4-8d25-6956077ba269") });
migrationBuilder.CreateIndex(
name: "IX_Node_ParentId",
table: "Node",
column: "ParentId");
migrationBuilder.CreateIndex(
name: "IX_Node_ManagerId",
table: "Node",
column: "ManagerId");
migrationBuilder.CreateIndex(
name: "IX_UserMembers_AttachedMemberId",
table: "UserMembers",
column: "AttachedMemberId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserMembers");
migrationBuilder.DropTable(
name: "Node");
}
}
}

View File

@ -1,199 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using UserService.DatabaseLayer.DataModels;
namespace UserService.DatabaseLayer.Migrations
{
[DbContext(typeof(UserServiceDbContext))]
partial class UserServiceDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.7");
modelBuilder.Entity("UserService.Infrastructure.DataModels.MembersMember", b =>
{
b.Property<Guid>("MemberId")
.HasColumnType("TEXT");
b.Property<Guid>("AttachedMemberId")
.HasColumnType("TEXT");
b.HasKey("MemberId", "AttachedMemberId");
b.HasIndex("AttachedMemberId");
b.ToTable("UserMembers");
b.HasData(
new
{
MemberId = new Guid("a830a548-8b92-4a95-aa8e-c71ae814c6a3"),
AttachedMemberId = new Guid("fd9f5d95-0898-47d4-8d25-6956077ba269")
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("CommonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("Discriminator")
.IsRequired()
.HasColumnType("TEXT");
b.Property<Guid?>("ParentId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("Node");
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.Member", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
b.HasDiscriminator().HasValue("Member");
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
b.Property<Guid?>("ManagerId")
.HasColumnType("TEXT");
b.HasIndex("ManagerId");
b.HasDiscriminator().HasValue("OrganizationUnit");
b.HasData(
new
{
Id = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"),
CommonName = "Users"
},
new
{
Id = new Guid("c94f4749-b7c7-418d-8c10-bc4253c4b913"),
CommonName = "Groups"
},
new
{
Id = new Guid("c743fff4-9bdf-45a4-b4c9-391f6fc46433"),
CommonName = "Germany",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551")
},
new
{
Id = new Guid("cecbf557-59cc-475c-b136-02da39aa4911"),
CommonName = "USA",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551")
},
new
{
Id = new Guid("89e1d70e-da3d-4cc9-81f1-a2fa76a6d33b"),
CommonName = "Arizona",
ParentId = new Guid("cecbf557-59cc-475c-b136-02da39aa4911")
},
new
{
Id = new Guid("97ad8c82-c5ea-4de1-a474-bf25418a9533"),
CommonName = "France",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551")
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.SecurityGroup", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
b.HasDiscriminator().HasValue("SecurityGroup");
b.HasData(
new
{
Id = new Guid("a830a548-8b92-4a95-aa8e-c71ae814c6a3"),
CommonName = "Global Admin",
ParentId = new Guid("c94f4749-b7c7-418d-8c10-bc4253c4b913")
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.User", b =>
{
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
b.Property<string>("EMail")
.HasColumnType("TEXT");
b.Property<string>("FirstName")
.HasColumnType("TEXT");
b.Property<bool>("IsActive")
.HasColumnType("INTEGER");
b.Property<string>("LastName")
.HasColumnType("TEXT");
b.HasDiscriminator().HasValue("User");
b.HasData(
new
{
Id = new Guid("fd9f5d95-0898-47d4-8d25-6956077ba269"),
CommonName = "holger",
ParentId = new Guid("c2366c9c-e79a-45c8-933c-40d0301b2551"),
IsActive = true
});
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.MembersMember", b =>
{
b.HasOne("UserService.Infrastructure.DataModels.Member", "AttachedMember")
.WithMany("MemberOf")
.HasForeignKey("AttachedMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UserService.Infrastructure.DataModels.Member", "Member")
.WithMany("Members")
.HasForeignKey("MemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
{
b.HasOne("UserService.Infrastructure.DataModels.Node", "Parent")
.WithMany("Children")
.HasForeignKey("ParentId");
});
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
{
b.HasOne("UserService.Infrastructure.DataModels.Member", "Manager")
.WithMany()
.HasForeignKey("ManagerId");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,63 +0,0 @@
#nullable enable
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
namespace UserService.DatabaseLayer.Repositories
{
public class BaseRepository<T> where T : Node
{
protected BaseRepository(Func<UserServiceDbContext, DbSet<T>> context)
{
Context = context;
}
protected Func<UserServiceDbContext, DbSet<T>> Context { get; }
public async Task AddAsync(T entity, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
await Context(db).AddAsync(@entity, token).ConfigureAwait(false);
await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public virtual async Task DeleteAsync(T entity, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
Context(db).Remove(entity);
await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public virtual async Task<IReadOnlyList<T>> GetAllAsync(Expression<Func<T, bool>>? predicate = null, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
return await Context(db)
.Include(x => x.Parent)
.WhereOrDefault(predicate)
.ToListAsync(token)
.ConfigureAwait(false);
}
public virtual async Task<T?> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
return await Context(db)
.Include(x => x.Parent)
.FirstOrDefaultAsync(predicate, token)
.ConfigureAwait(false);
}
public virtual async Task<bool> UpdateAsync(T entity, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
Context(db).Update(entity);
var items = await db.SaveChangesAsync(token).ConfigureAwait(false);
return items > 0;
}
}
}

View File

@ -4,11 +4,11 @@ using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using UserService.Infrastructure.DataModels;
using DataModels;
namespace UserService.DatabaseLayer.Repositories
{
public interface IRepository<T> where T : Node
public interface IRepository<T> where T : class
{
Task<IReadOnlyList<T>> GetAllAsync(Expression<Func<T, bool>>? predicate = null, CancellationToken token = default);
Task<T?> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken token = default);

View File

@ -1,51 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
using DataModels;
namespace UserService.DatabaseLayer.Repositories
{
public class OrganizationUnitsRepository : BaseRepository<OrganizationUnit>, IOrganizationUnitsRepository
public class OrganizationUnitsRepository : IOrganizationUnitsRepository
{
public OrganizationUnitsRepository() : base(x => x.OrganizationUnits)
/// <inheritdoc />
public async Task<IReadOnlyList<OrganizationUnit>> GetAllAsync(Expression<Func<OrganizationUnit, bool>>? predicate = null, CancellationToken token = default)
{
throw new NotImplementedException();
}
/// <inheritdoc cref="GetAllAsync" />
public override async Task<IReadOnlyList<OrganizationUnit>> GetAllAsync(
Expression<Func<OrganizationUnit, bool>>? predicate = null, CancellationToken token = default)
/// <inheritdoc />
public async Task<OrganizationUnit?> GetAsync(Expression<Func<OrganizationUnit, bool>> predicate, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
var rootOus = await Context(db)
.Include(x => x.Parent)
.WhereOrDefault(predicate)
.ToListAsync(token).ConfigureAwait(false);
throw new NotImplementedException();
}
IEnumerable<OrganizationUnit> Rec(Node node)
{
if (!(node is OrganizationUnit organizationUnit)) yield break;
yield return organizationUnit;
foreach (var ouChild in rootOus.Where(x => x.ParentId != null && x.ParentId == organizationUnit.Id))
{
foreach (var unit in Rec(ouChild))
{
yield return unit;
}
}
}
/// <inheritdoc />
public async Task AddAsync(OrganizationUnit entity, CancellationToken token = default)
{
throw new NotImplementedException();
}
var result = new List<OrganizationUnit>();
foreach (var ou in rootOus.Where(x => x.ParentId is null))
{
result.AddRange(Rec(ou));
}
/// <inheritdoc />
public async Task<bool> UpdateAsync(OrganizationUnit entity, CancellationToken token = default)
{
throw new NotImplementedException();
}
return result;
/// <inheritdoc />
public async Task DeleteAsync(OrganizationUnit entity, CancellationToken token = default)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,53 +1,44 @@
#nullable enable
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
using DataModels;
namespace UserService.DatabaseLayer.Repositories
{
public class SecurityGroupsRepository : BaseRepository<SecurityGroup>, ISecurityGroupsRepository
public class SecurityGroupsRepository : ISecurityGroupsRepository
{
public SecurityGroupsRepository() : base(x => x.SecurityGroups)
/// <inheritdoc />
public async Task<IReadOnlyList<SecurityGroup>> GetAllAsync(Expression<Func<SecurityGroup, bool>>? predicate = null, CancellationToken token = default)
{
throw new NotImplementedException();
}
public override async Task<IReadOnlyList<SecurityGroup>> GetAllAsync(Expression<Func<SecurityGroup, bool>>? predicate = null, CancellationToken token = default)
/// <inheritdoc />
public async Task<SecurityGroup?> GetAsync(Expression<Func<SecurityGroup, bool>> predicate, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
return await Context(db)
.Include(x => x.Parent)
.Include(x => x.Members)
.ThenInclude(x=> x.AttachedMember)
.WhereOrDefault(predicate)
.ToListAsync(token).ConfigureAwait(false);
throw new NotImplementedException();
}
public override async Task<SecurityGroup?> GetAsync(Expression<Func<SecurityGroup, bool>> predicate, CancellationToken token = default)
/// <inheritdoc />
public async Task AddAsync(SecurityGroup entity, CancellationToken token = default)
{
await using var db = new UserServiceDbContext();
return await Context(db)
.Include(x => x.Parent)
.Include(x => x.Members)
.ThenInclude(x=> x.AttachedMember)
.FirstOrDefaultAsync(predicate, token).ConfigureAwait(false);
throw new NotImplementedException();
}
public override async Task<bool> UpdateAsync(SecurityGroup entity, CancellationToken token = default)
/// <inheritdoc />
public async Task<bool> UpdateAsync(SecurityGroup entity, CancellationToken token = default)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
throw new NotImplementedException();
}
await using var db = new UserServiceDbContext();
Context(db).Update(entity);
db.UserMembers.UpdateRange(entity.Members);
var items = await db.SaveChangesAsync(token).ConfigureAwait(false);
return items > 0;
/// <inheritdoc />
public async Task DeleteAsync(SecurityGroup entity, CancellationToken token = default)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,11 +1,68 @@
using UserService.Infrastructure.DataModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using DataModels;
using LinqToDB;
using LinqToDB.Data;
namespace UserService.DatabaseLayer.Repositories
{
public class UsersRepository : BaseRepository<User>, IUsersRepository
public class UsersRepository : IUsersRepository
{
public UsersRepository() : base(x => x.Users)
public UsersRepository()
{
DataConnection.DefaultSettings = new MySettings();
}
/// <inheritdoc />
public async Task<IReadOnlyList<User>> GetAllAsync(Expression<Func<User, bool>>? predicate = null,
CancellationToken token = default)
{
await using var db = new UserServiceDB();
return await db.Users.LoadWith(x=> x.Member).LoadWith(x=> x.Member.Node).WhereOrDefault(predicate).ToListAsync(token: token).ConfigureAwait(false);
}
/// <inheritdoc />
public async Task<User?> GetAsync(Expression<Func<User, bool>> predicate, CancellationToken token = default)
{
await using var db = new UserServiceDB();
var result = await db.Users.FirstOrDefaultAsync(predicate, token: token).ConfigureAwait(false);
return result;
}
/// <inheritdoc />
public async Task AddAsync(User entity, CancellationToken token = default)
{
await using var db = new UserServiceDB();
var nodeId =
await db.Nodes.InsertWithInt32IdentityAsync(() => new Node {CommonName = "holger"}, token: token);
await db.Members.InsertAsync(() => new Member {Id = nodeId}, token: token);
await db.Users.InsertAsync(() => new User
{
Id = nodeId,
FirstName = entity.FirstName,
LastName = entity.LastName,
IsActive = entity.IsActive
}, token: token).ConfigureAwait(false);
}
/// <inheritdoc />
public async Task<bool> UpdateAsync(User entity, CancellationToken token = default)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public async Task DeleteAsync(User entity, CancellationToken token = default)
{
await using var db = new UserServiceDB();
await db.Users.DeleteAsync(x => x.Id == entity.Id, token: token);
}
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
@ -7,19 +7,38 @@
</PropertyGroup>
<ItemGroup>
<None Include="DataModels\UserDatabase.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>UserDatabase.tt</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="linq2db.MySql" Version="3.1.3" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UserService.Infrastructure\UserService.Infrastructure.csproj" />
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="DataModels\UserDatabase.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>UserDatabase.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="DataModels\UserDatabase.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>UserDatabase.generated.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@ -24,7 +24,7 @@ namespace UserService.Infrastructure.DataModels
public int CompareTo(Node? other)
{
if (ReferenceEquals(this, other)) return 0;
if (ReferenceEquals(null, other)) return 1;
if (other is null) return 1;
var commonNameComparison = string.Compare(CommonName, other.CommonName, StringComparison.Ordinal);
if (commonNameComparison != 0) return commonNameComparison;
return Id.CompareTo(other.Id);

View File

@ -10,4 +10,8 @@
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="DataModels\" />
</ItemGroup>
</Project>

View File

@ -1,11 +1,7 @@
using Microsoft.EntityFrameworkCore;
using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
using DataModels;
using UserService.DatabaseLayer.Repositories;
namespace UserService.Test
{
@ -19,40 +15,20 @@ namespace UserService.Test
[Test]
public async Task Test1()
{
await using var db = new UserServiceDbContext();
var user = await db.Users.FirstOrDefaultAsync().ConfigureAwait(false);
var secGroup = await db.SecurityGroups.FirstOrDefaultAsync().ConfigureAwait(false);
var ous = await db.OrganizationUnits.ToListAsync().ConfigureAwait(false);
var mo = await db.UserMembers.ToListAsync().ConfigureAwait(false);
var securityGroupsOfUser = user.GetSecurityGroups();
var usersOfSecurityGroup = secGroup.GetAttachedMembers();
//var testGroup = new SecurityGroup {CommonName = "Test", Parent = ous.Last()};
//await db.SecurityGroups.AddAsync(testGroup);
//var testgroup = await db.SecurityGroups.FindAsync(1);
//testgroup.Members.AddAsync(new UserMember{MemberId = testgroup.Id, UserId = user.Id});
//await db.SaveChangesAsync();
Assert.Pass();
var usersRepository = new UsersRepository();
var users = await usersRepository.GetAllAsync();
Assert.AreEqual(users.Count, 1);
}
[Test]
public async Task Test2()
{
await using var db = new UserServiceDbContext();
var ous = await db.OrganizationUnits.ToListAsync().ConfigureAwait(false);
var sb = new StringBuilder();
NewMethod(ous, null, 0, ref sb);
var result = sb.ToString();
Assert.Pass();
}
private static void NewMethod(IEnumerable<OrganizationUnit> ous, Node parent, int level, ref StringBuilder sb)
{
foreach (var unit in ous.Where(x => x.Parent == parent))
var usersRepository = new UsersRepository();
var user = new User
{
sb.AppendLine(string.Concat(Enumerable.Repeat(' ', 4 * level)) + unit.CommonName);
NewMethod(unit.Children.OfType<OrganizationUnit>(), unit, level + 1, ref sb);
}
FirstName = "Holger", LastName = "Börchers", IsActive = true
};
await usersRepository.AddAsync(user);
}
}
}

View File

@ -19,7 +19,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UserService\UserService.csproj" />
<ProjectReference Include="..\UserService.DatabaseLayer\UserService.DatabaseLayer.csproj" />
</ItemGroup>
</Project>