4 Commits

25 changed files with 371 additions and 310 deletions

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="RIDER_MODULE" version="4"> <module type="RIDER_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.7.0/build/netcoreapp2.1" /> <content url="file://$USER_HOME$/.nuget/packages/linq2db.mysql/3.1.3/contentFiles/any/any/LinqToDB.Templates" />
<content url="file://$USER_HOME$/.nuget/packages/microsoft.testplatform.testhost/16.7.0/build/netcoreapp2.1/x64/testhost.dll" /> <content url="file://$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.7.1/build/netcoreapp2.1" />
<content url="file://$USER_HOME$/.nuget/packages/microsoft.testplatform.testhost/16.7.0/build/netcoreapp2.1/x64/testhost.exe" /> <content url="file://$USER_HOME$/.nuget/packages/microsoft.testplatform.testhost/16.7.1/build/netcoreapp2.1/x64/testhost.dll" />
<content url="file://$USER_HOME$/.nuget/packages/microsoft.testplatform.testhost/16.7.1/build/netcoreapp2.1/x64/testhost.exe" />
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.17.0/build/netcoreapp2.1/NUnit3.TestAdapter.dll" /> <content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.17.0/build/netcoreapp2.1/NUnit3.TestAdapter.dll" />
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.17.0/build/netcoreapp2.1/NUnit3.TestAdapter.pdb" /> <content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.17.0/build/netcoreapp2.1/NUnit3.TestAdapter.pdb" />
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.17.0/build/netcoreapp2.1/nunit.engine.api.dll" /> <content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.17.0/build/netcoreapp2.1/nunit.engine.api.dll" />

View File

@ -1,36 +0,0 @@
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

@ -0,0 +1,12 @@
using LinqToDB.Configuration;
namespace UserService.DatabaseLayer.DataModels
{
public class ConnectionStringSettings : IConnectionStringSettings
{
public string ConnectionString { get; } = @"Server=srvbo;Database=UserService2;Uid=UserDbAdmin;Pwd=12345678;";
public string Name { get; } = "UserServiceDb";
public string ProviderName { get; } = "MySqlServer";
public bool IsGlobal { get; }
}
}

View File

@ -15,29 +15,25 @@ using System.Linq;
using LinqToDB; using LinqToDB;
using LinqToDB.Mapping; using LinqToDB.Mapping;
namespace DataModels namespace UserService.DatabaseLayer.DataModels
{ {
/// <summary> /// <summary>
/// Database : UserService /// Database : UserService2
/// Data Source : srvbo /// Data Source : srvbo
/// Server Version : 5.5.5-10.3.22-MariaDB-1ubuntu1 /// Server Version : 5.5.5-10.3.22-MariaDB-1ubuntu1
/// </summary> /// </summary>
public partial class UserServiceDB : LinqToDB.Data.DataConnection public partial class UserService2DB : LinqToDB.Data.DataConnection
{ {
public ITable<Member> Members { get { return this.GetTable<Member>(); } } public ITable<IsMemberOf> IsMemberOfs { get { return this.GetTable<IsMemberOf>(); } }
public ITable<MembersMember> MembersMembers { get { return this.GetTable<MembersMember>(); } } public ITable<NodeModel> NodeModels { get { return this.GetTable<NodeModel>(); } }
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() public UserService2DB()
{ {
InitDataContext(); InitDataContext();
InitMappingSchema(); InitMappingSchema();
} }
public UserServiceDB(string configuration) public UserService2DB(string configuration)
: base(configuration) : base(configuration)
{ {
InitDataContext(); InitDataContext();
@ -48,167 +44,70 @@ namespace DataModels
partial void InitMappingSchema(); partial void InitMappingSchema();
} }
[Table("Members")] [Table("IsMemberOf")]
public partial class Member public partial class IsMemberOf
{ {
[Column, NotNull] public int Id { get; set; } // int(11) [PrimaryKey(1), NotNull] public int NodeId { get; set; } // int(11)
[PrimaryKey(2), NotNull] public int NodeMemberId { get; set; } // int(11)
#region Associations #region Associations
/// <summary> /// <summary>
/// MembersMember_ibfk_2_BackReference /// IsMemberOf_ibfk_1
/// </summary> /// </summary>
[Association(ThisKey="Id", OtherKey="AttachedMemberId", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)] [Association(ThisKey="NodeId", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="IsMemberOf_ibfk_1", BackReferenceName="IsMemberOfibfks")]
public IEnumerable<MembersMember> MembersMemberibfks { get; set; } = null!; public NodeModel Node { get; set; } = null!;
/// <summary> /// <summary>
/// Members_ibfk_2 /// IsMemberOf_ibfk_2
/// </summary> /// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="Members_ibfk_2", BackReferenceName="Membersibfks")] [Association(ThisKey="NodeMemberId", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="IsMemberOf_ibfk_2", BackReferenceName="IsMemberOfIbfk2BackReferences")]
public Node Node { get; set; } = null!; public NodeModel NodeMember { 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 #endregion
} }
[Table("MembersMember")] [Table("NodeModels")]
public partial class MembersMember public partial class NodeModel
{ {
[PrimaryKey(1), NotNull] public int MemberId { get; set; } // int(11) [PrimaryKey, Identity ] public int Id { get; set; } // int(11)
[PrimaryKey(2), NotNull] public int AttachedMemberId { get; set; } // int(11) [Column, NotNull ] public string CommonName { get; set; } = null!; // varchar(64)
#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? FirstName { get; set; } // text
[Column, Nullable] public string? LastName { get; set; } // text [Column, Nullable] public string? LastName { get; set; } // text
[Column, NotNull ] public bool IsActive { get; set; } // bit(1) [Column, Nullable] public string? Description { get; set; } // text
[Column, Nullable] public int? ParentId { get; set; } // int(11)
[Column, Nullable] public int? ManagerId { get; set; } // int(11)
[Column, Nullable] public string? EMail { get; set; } // text
[Column, Nullable] public bool? IsActive { get; set; } // bit(1)
[Column, NotNull ] public string Discriminator { get; set; } = null!; // varchar(16)
#region Associations #region Associations
/// <summary> /// <summary>
/// Users_ibfk_2 /// IsMemberOf_ibfk_2_BackReference
/// </summary> /// </summary>
[Association(ThisKey="Id", OtherKey="Id", CanBeNull=false, Relationship=Relationship.ManyToOne, KeyName="Users_ibfk_2", BackReferenceName="Usersibfks")] [Association(ThisKey="Id", OtherKey="NodeMemberId", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public Member Member { get; set; } = null!; public IEnumerable<IsMemberOf> IsMemberOfIbfk2BackReferences { get; set; } = null!;
/// <summary>
/// IsMemberOf_ibfk_1_BackReference
/// </summary>
[Association(ThisKey="Id", OtherKey="NodeId", CanBeNull=true, Relationship=Relationship.OneToMany, IsBackReference=true)]
public IEnumerable<IsMemberOf> IsMemberOfibfks { get; set; } = null!;
#endregion #endregion
} }
public static partial class TableExtensions public static partial class TableExtensions
{ {
public static MembersMember Find(this ITable<MembersMember> table, int MemberId, int AttachedMemberId) public static IsMemberOf Find(this ITable<IsMemberOf> table, int NodeId, int NodeMemberId)
{ {
return table.FirstOrDefault(t => return table.FirstOrDefault(t =>
t.MemberId == MemberId && t.NodeId == NodeId &&
t.AttachedMemberId == AttachedMemberId); t.NodeMemberId == NodeMemberId);
} }
public static Node Find(this ITable<Node> table, int Id) public static NodeModel Find(this ITable<NodeModel> table, int Id)
{ {
return table.FirstOrDefault(t => return table.FirstOrDefault(t =>
t.Id == Id); t.Id == Id);

View File

@ -6,11 +6,11 @@
<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> <# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #>
<# <#
NamespaceName = "DataModels"; NamespaceName = "UserService.DatabaseLayer.DataModels";
// to configure GetSchemaOptions properties, add them here, before load metadata call // to configure GetSchemaOptions properties, add them here, before load metadata call
LoadMySqlMetadata("srvbo", "UserService", "UserDbAdmin", "12345678"); LoadMySqlMetadata("srvbo", "UserService2", "UserDbAdmin", "12345678");
// LoadMySqlMetadata(string connectionString); // LoadMySqlMetadata(string connectionString);
// to adjust loaded database model before generation, add your code here, after load metadata, but before GenerateModel() call // to adjust loaded database model before generation, add your code here, after load metadata, but before GenerateModel() call

View File

@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Linq;
using LinqToDB.Configuration;
namespace UserService.DatabaseLayer.DataModels
{
public class UserDbSettings : 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();
}
}
}
}

View File

@ -0,0 +1,13 @@
using LinqToDB.Data;
using UserService.DatabaseLayer.DataModels;
namespace UserService.DatabaseLayer.Repositories
{
public abstract class BaseRepository
{
protected BaseRepository()
{
DataConnection.DefaultSettings = new UserDbSettings();
}
}
}

View File

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

View File

@ -1,42 +1,87 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using DataModels; using LinqToDB;
using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
namespace UserService.DatabaseLayer.Repositories namespace UserService.DatabaseLayer.Repositories
{ {
public class OrganizationUnitsRepository : IOrganizationUnitsRepository public class OrganizationUnitsRepository : BaseRepository, IOrganizationUnitsRepository
{ {
/// <inheritdoc /> public async Task<IReadOnlyList<OrganizationUnit>> GetAllAsync(Expression<Func<NodeModel, bool>>? predicate = null, CancellationToken token = default)
public async Task<IReadOnlyList<OrganizationUnit>> GetAllAsync(Expression<Func<OrganizationUnit, bool>>? predicate = null, CancellationToken token = default)
{ {
throw new NotImplementedException(); await using var db = new UserService2DB();
var organizationUnits = await db.NodeModels
.Where(x => x.Discriminator == nameof(OrganizationUnit))
.WhereOrDefault(predicate)
.Select(x => new OrganizationUnit
{
Id = x.Id,
CommonName = x.CommonName,
Description = x.Description,
ParentId = x.ParentId,
})
.ToListAsync(token).ConfigureAwait(false);
return organizationUnits;
} }
/// <inheritdoc /> public async Task<OrganizationUnit?> GetAsync(Expression<Func<NodeModel, bool>> predicate, CancellationToken token = default)
public async Task<OrganizationUnit?> GetAsync(Expression<Func<OrganizationUnit, bool>> predicate, CancellationToken token = default)
{ {
throw new NotImplementedException(); await using var db = new UserService2DB();
var result = await db.NodeModels
.Where(predicate)
.Select(x => new OrganizationUnit
{
Id = x.Id,
CommonName = x.CommonName,
Description = x.Description,
ParentId = x.ParentId,
ManagerId = x.ManagerId,
}).FirstOrDefaultAsync(token).ConfigureAwait(false);
return result;
} }
/// <inheritdoc /> public async Task<int> AddAsync(OrganizationUnit entity, CancellationToken token = default)
public async Task AddAsync(OrganizationUnit entity, CancellationToken token = default)
{ {
throw new NotImplementedException(); if (entity == null) throw new ArgumentNullException(nameof(entity));
await using var db = new UserService2DB();
var managerId = entity.Manager?.Id;
return await db.NodeModels.InsertWithInt32IdentityAsync(() => new NodeModel
{
CommonName = entity.CommonName,
Description = entity.Description,
Discriminator = nameof(OrganizationUnit),
ParentId = entity.ParentId,
ManagerId = managerId,
}, token).ConfigureAwait(false);
} }
/// <inheritdoc />
public async Task<bool> UpdateAsync(OrganizationUnit entity, CancellationToken token = default) public async Task<bool> UpdateAsync(OrganizationUnit entity, CancellationToken token = default)
{ {
throw new NotImplementedException(); if (entity == null) throw new ArgumentNullException(nameof(entity));
await using var db = new UserService2DB();
var managerId = entity.Manager?.Id;
var changedRows = await db.NodeModels.UpdateAsync(x => x.Id == entity.Id,
x => new NodeModel
{
CommonName = entity.CommonName,
Description = entity.Description,
Discriminator = nameof(OrganizationUnit),
ParentId = entity.ParentId,
ManagerId = managerId,
}, token).ConfigureAwait(false);
return changedRows > 0;
} }
/// <inheritdoc />
public async Task DeleteAsync(OrganizationUnit entity, CancellationToken token = default) public async Task DeleteAsync(OrganizationUnit entity, CancellationToken token = default)
{ {
throw new NotImplementedException(); await using var db = new UserService2DB();
await db.NodeModels.DeleteAsync(x => x.Id == entity.Id, token).ConfigureAwait(false);
} }
} }
} }

View File

@ -5,40 +5,39 @@ using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using DataModels; using LinqToDB;
using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
namespace UserService.DatabaseLayer.Repositories namespace UserService.DatabaseLayer.Repositories
{ {
public class SecurityGroupsRepository : ISecurityGroupsRepository public class SecurityGroupsRepository : ISecurityGroupsRepository
{ {
/// <inheritdoc /> public Task<IReadOnlyList<SecurityGroup>> GetAllAsync(Expression<Func<NodeModel, bool>>? predicate = null, CancellationToken token = default)
public async Task<IReadOnlyList<SecurityGroup>> GetAllAsync(Expression<Func<SecurityGroup, bool>>? predicate = null, CancellationToken token = default) {
throw new NotImplementedException();
}
public Task<SecurityGroup?> GetAsync(Expression<Func<NodeModel, bool>> predicate, CancellationToken token = default)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <inheritdoc /> public Task<int> AddAsync(SecurityGroup entity, CancellationToken token = default)
public async Task<SecurityGroup?> GetAsync(Expression<Func<SecurityGroup, bool>> predicate, CancellationToken token = default)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <inheritdoc /> public Task<bool> UpdateAsync(SecurityGroup entity, CancellationToken token = default)
public async Task AddAsync(SecurityGroup entity, CancellationToken token = default)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <inheritdoc />
public async Task<bool> UpdateAsync(SecurityGroup entity, CancellationToken token = default)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public async Task DeleteAsync(SecurityGroup entity, CancellationToken token = default) public async Task DeleteAsync(SecurityGroup entity, CancellationToken token = default)
{ {
throw new NotImplementedException(); await using var db = new UserService2DB();
await db.NodeModels.DeleteAsync(x => x.Id == entity.Id, token).ConfigureAwait(false);
} }
} }
} }

View File

@ -4,65 +4,98 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using DataModels;
using LinqToDB; using LinqToDB;
using LinqToDB.Data; using UserService.DatabaseLayer.DataModels;
using UserService.Infrastructure.DataModels;
namespace UserService.DatabaseLayer.Repositories namespace UserService.DatabaseLayer.Repositories
{ {
public class UsersRepository : IUsersRepository public class UsersRepository : BaseRepository, IUsersRepository
{ {
public UsersRepository()
{
DataConnection.DefaultSettings = new MySettings();
}
/// <inheritdoc /> /// <inheritdoc />
public async Task<IReadOnlyList<User>> GetAllAsync(Expression<Func<User, bool>>? predicate = null, public async Task<IReadOnlyList<User>> GetAllAsync(Expression<Func<NodeModel, bool>>? predicate = null,
CancellationToken token = default) CancellationToken token = default)
{ {
await using var db = new UserServiceDB(); await using var db = new UserService2DB();
return await db.Users.LoadWith(x=> x.Member).LoadWith(x=> x.Member.Node).WhereOrDefault(predicate).ToListAsync(token: token).ConfigureAwait(false); var users = await db.NodeModels
.Where(x => x.Discriminator == nameof(User))
.WhereOrDefault(predicate)
.Select(x => new User
{
Id = x.Id,
CommonName = x.CommonName,
Description = x.Description,
FirstName = x.FirstName,
LastName = x.LastName,
IsActive = x.IsActive ?? false,
EMail = x.EMail,
ParentId = x.ParentId,
})
.ToListAsync(token).ConfigureAwait(false);
return users;
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task<User?> GetAsync(Expression<Func<User, bool>> predicate, CancellationToken token = default) public async Task<User?> GetAsync(Expression<Func<NodeModel, bool>> predicate,
CancellationToken token = default)
{ {
await using var db = new UserServiceDB(); await using var db = new UserService2DB();
var result = await db.Users.FirstOrDefaultAsync(predicate, token: token).ConfigureAwait(false); var result = await db.NodeModels
.Where(predicate)
.Select(x => new User
{
Id = x.Id,
CommonName = x.CommonName,
Description = x.Description,
FirstName = x.FirstName,
LastName = x.LastName,
IsActive = x.IsActive ?? false,
EMail = x.EMail
}).FirstOrDefaultAsync(token).ConfigureAwait(false);
return result; return result;
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task AddAsync(User entity, CancellationToken token = default) public async Task<int> AddAsync(User entity, CancellationToken token = default)
{ {
await using var db = new UserServiceDB(); await using var db = new UserService2DB();
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 return await db.NodeModels.InsertWithInt32IdentityAsync(() => new NodeModel
{ {
Id = nodeId, CommonName = entity.CommonName,
FirstName = entity.FirstName, FirstName = entity.FirstName,
LastName = entity.LastName, LastName = entity.LastName,
IsActive = entity.IsActive Description = entity.Description,
EMail = entity.EMail,
}, token: token).ConfigureAwait(false); IsActive = entity.IsActive,
Discriminator = nameof(User),
}, token).ConfigureAwait(false);
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task<bool> UpdateAsync(User entity, CancellationToken token = default) public async Task<bool> UpdateAsync(User entity, CancellationToken token = default)
{ {
throw new NotImplementedException(); await using var db = new UserService2DB();
var changedRows = await db.NodeModels.UpdateAsync(x => x.Id == entity.Id,
x => new NodeModel
{
CommonName = entity.CommonName,
FirstName = entity.FirstName,
LastName = entity.LastName,
Description = entity.Description,
EMail = entity.EMail,
IsActive = entity.IsActive,
Discriminator = nameof(User),
}, token).ConfigureAwait(false);
return changedRows > 0;
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task DeleteAsync(User entity, CancellationToken token = default) public async Task DeleteAsync(User entity, CancellationToken token = default)
{ {
await using var db = new UserServiceDB(); await using var db = new UserService2DB();
await db.Users.DeleteAsync(x => x.Id == entity.Id, token: token); await db.NodeModels.DeleteAsync(x => x.Id == entity.Id, token).ConfigureAwait(false);
} }
} }
} }

View File

@ -22,6 +22,10 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UserService.Infrastructure\UserService.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" /> <Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup> </ItemGroup>

View File

@ -4,8 +4,6 @@ namespace UserService.Infrastructure.DataModels
{ {
public abstract class Member : Node public abstract class Member : Node
{ {
public ISet<MembersMember> Members { get; set; } = new HashSet<MembersMember>();
public ISet<MembersMember> MemberOf { get; set; } = null!; public ISet<MembersMember> MemberOf { get; set; } = null!;
} }
} }

View File

@ -1,33 +1,18 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace UserService.Infrastructure.DataModels namespace UserService.Infrastructure.DataModels
{ {
public abstract class Node : ICloneable, IComparable<Node> public abstract class Node : ICloneable
{ {
public Guid Id { get; set; } public int Id { get; set; }
[Required] public string CommonName { get; set; } = null!; [Required] public string CommonName { get; set; } = null!;
public string? Description { get; set; } public string? Description { get; set; }
public ISet<Node> Children { get; set; } = new SortedSet<Node>();
public Node? Parent { get; set; } //Parent
public Guid? ParentId { get; set; }
public override string ToString() => CommonName; public override string ToString() => CommonName;
public int? ParentId { get; set; }
public int Level => Parent?.Level + 1 ?? 0;
/// <inheritdoc /> /// <inheritdoc />
public virtual object Clone() => MemberwiseClone(); public virtual object Clone() => MemberwiseClone();
public int CompareTo(Node? other)
{
if (ReferenceEquals(this, other)) return 0;
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

@ -3,5 +3,6 @@
public class OrganizationUnit : Node public class OrganizationUnit : Node
{ {
public Member? Manager { get; set; } public Member? Manager { get; set; }
public int? ManagerId { get; set; }
} }
} }

View File

@ -1,6 +1,9 @@
namespace UserService.Infrastructure.DataModels using System.Collections.Generic;
namespace UserService.Infrastructure.DataModels
{ {
public class SecurityGroup : Member public class SecurityGroup : Member
{ {
public ISet<MembersMember> Members { get; set; } = new HashSet<MembersMember>();
} }
} }

View File

@ -1,6 +1,4 @@
using System.Collections.Generic; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace UserService.Infrastructure.DataModels namespace UserService.Infrastructure.DataModels
{ {

View File

@ -0,0 +1,61 @@
using System;
using System.Threading.Tasks;
using NUnit.Framework;
using UserService.DatabaseLayer.Repositories;
using UserService.Infrastructure.DataModels;
namespace UserService.Test
{
public class OrgUnitRepositoryTests
{
private OrganizationUnitsRepository _repository;
[OneTimeSetUp]
public void SetUp()
{
_repository = new OrganizationUnitsRepository();
}
[Test]
[Order(2)]
public async Task Test1()
{
var entities = await _repository.GetAllAsync().ConfigureAwait(false);
Assert.AreEqual(entities.Count, 4);
}
[Test]
[Order(1)]
public async Task Test2()
{
var ou = new OrganizationUnit {CommonName = "Users", Description = "Users"};
var id = await _repository.AddAsync(ou).ConfigureAwait(false);
ou = new OrganizationUnit {CommonName = "USA", Description = "Users", ParentId = id};
id = await _repository.AddAsync(ou).ConfigureAwait(false);
ou = new OrganizationUnit { CommonName = "Arizona", Description = "Users", ParentId = id };
id = await _repository.AddAsync(ou).ConfigureAwait(false);
ou = new OrganizationUnit { CommonName = "Germany", Description = "Users", ParentId = id };
await _repository.AddAsync(ou).ConfigureAwait(false);
}
[Test]
[Order(3)]
public async Task Test3()
{
var entity = await _repository.GetAsync(x => x.CommonName == "Users").ConfigureAwait(false);
entity.Description = DateTime.Now.ToString("O");
await _repository.UpdateAsync(entity).ConfigureAwait(false);
}
[Test]
[Order(4)]
public async Task Test4()
{
var entity = await _repository.GetAllAsync().ConfigureAwait(false);
foreach (var organizationUnit in entity)
{
await _repository.DeleteAsync(organizationUnit).ConfigureAwait(false);
}
}
}
}

View File

@ -1,34 +0,0 @@
using NUnit.Framework;
using System.Threading.Tasks;
using DataModels;
using UserService.DatabaseLayer.Repositories;
namespace UserService.Test
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public async Task Test1()
{
var usersRepository = new UsersRepository();
var users = await usersRepository.GetAllAsync();
Assert.AreEqual(users.Count, 1);
}
[Test]
public async Task Test2()
{
var usersRepository = new UsersRepository();
var user = new User
{
FirstName = "Holger", LastName = "B<>rchers", IsActive = true
};
await usersRepository.AddAsync(user);
}
}
}

View File

@ -0,0 +1,58 @@
using NUnit.Framework;
using System;
using System.Threading.Tasks;
using UserService.DatabaseLayer.Repositories;
using UserService.Infrastructure.DataModels;
namespace UserService.Test
{
public class UserRepositoryTests
{
private UsersRepository _repository;
[OneTimeSetUp]
public void SetUp()
{
_repository = new UsersRepository();
}
[Test]
[Order(2)]
public async Task Test1()
{
var users = await _repository.GetAllAsync().ConfigureAwait(false);
Assert.AreEqual(users.Count, 1);
}
[Test]
[Order(1)]
public async Task Test2()
{
var user = new User
{
CommonName = "holger",
FirstName = "Holger",
LastName = "Börchers",
IsActive = true
};
await _repository.AddAsync(user).ConfigureAwait(false);
}
[Test]
[Order(3)]
public async Task Test3()
{
var user = await _repository.GetAsync(x => x.CommonName == "holger").ConfigureAwait(false);
user.Description = DateTime.Now.ToString("O");
await _repository.UpdateAsync(user).ConfigureAwait(false);
}
[Test]
[Order(4)]
public async Task Test4()
{
var user = await _repository.GetAsync(x => x.CommonName == "holger").ConfigureAwait(false);
await _repository.DeleteAsync(user).ConfigureAwait(false);
}
}
}

View File

@ -39,7 +39,7 @@ namespace UserService.Pages
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
OrganizationUnits = (await OuRepository.GetAllAsync().ConfigureAwait(false)) OrganizationUnits = (await OuRepository.GetAllAsync().ConfigureAwait(false))
.Where(x => x.Parent is null) .Where(x => x.ParentId is null)
.ToList(); .ToList();
} }

View File

@ -77,7 +77,7 @@ else
<Select TValue="Guid?" SelectedValue="@((Guid?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" > <Select TValue="Guid?" SelectedValue="@((Guid?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" >
@foreach (var item in OrganizationUnits ?? Enumerable.Empty<OrganizationUnit>()) @foreach (var item in OrganizationUnits ?? Enumerable.Empty<OrganizationUnit>())
{ {
<SelectItem TValue="Guid" Value="@(item.Id)">@item.CommonName</SelectItem> <SelectItem TValue="int" Value="@(item.Id)">@item.CommonName</SelectItem>
} }
</Select> </Select>
</EditTemplate> </EditTemplate>

View File

@ -56,8 +56,8 @@ namespace UserService.Pages
if (arg == null) throw new ArgumentNullException(nameof(arg)); if (arg == null) throw new ArgumentNullException(nameof(arg));
var securityGroup = arg.Item; var securityGroup = arg.Item;
securityGroup.MapFields(arg.Values); securityGroup.MapFields(arg.Values);
securityGroup.Parent = //securityGroup.Parent =
OrganizationUnits?.FirstOrDefault(x => x.Id == (Guid?)arg.Values[nameof(Node.ParentId)]); // OrganizationUnits?.FirstOrDefault(x => x.Id == (Guid?)arg.Values[nameof(Node.Parent.Id)]);
var result = await SecurityGroupsRepository.UpdateAsync(securityGroup).ConfigureAwait(false); var result = await SecurityGroupsRepository.UpdateAsync(securityGroup).ConfigureAwait(false);
arg.Cancel = !result; arg.Cancel = !result;
} }
@ -98,9 +98,7 @@ namespace UserService.Pages
if (SelectedSecurityGroup is null) return; if (SelectedSecurityGroup is null) return;
if (!SelectedSecurityGroup.Members.Add(new MembersMember if (!SelectedSecurityGroup.Members.Add(new MembersMember
{ {
MemberId = SelectedSecurityGroup.Id,
Member = SelectedSecurityGroup, Member = SelectedSecurityGroup,
AttachedMemberId = SelectedMember.Id,
AttachedMember = SelectedMember AttachedMember = SelectedMember
})) }))
{ {

View File

@ -93,7 +93,7 @@ else
<Select TValue="Guid?" SelectedValue="@((Guid?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" > <Select TValue="Guid?" SelectedValue="@((Guid?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" >
@foreach (var item in OrganizationUnits ?? Enumerable.Empty<OrganizationUnit>()) @foreach (var item in OrganizationUnits ?? Enumerable.Empty<OrganizationUnit>())
{ {
<SelectItem TValue="Guid" Value="@(item.Id)">@item.CommonName</SelectItem> <SelectItem TValue="int" Value="@(item.Id)">@item.CommonName</SelectItem>
} }
</Select> </Select>
</EditTemplate> </EditTemplate>

View File

@ -39,7 +39,7 @@ namespace UserService.Pages
if (arg is null) throw new ArgumentNullException(nameof(arg)); if (arg is null) throw new ArgumentNullException(nameof(arg));
var user = arg.Item; var user = arg.Item;
await UsersRepository.AddAsync(user).ConfigureAwait(false); await UsersRepository.AddAsync(user).ConfigureAwait(false);
user.Parent = OrganizationUnits?.FirstOrDefault(x => x.Id == user.ParentId); //user.Parent = OrganizationUnits?.FirstOrDefault(x => x.Id == user.ParentId);
} }
protected override async Task RowDeletingCallback(CancellableRowChange<User> arg) protected override async Task RowDeletingCallback(CancellableRowChange<User> arg)
@ -71,7 +71,7 @@ namespace UserService.Pages
if (arg == null) throw new ArgumentNullException(nameof(arg)); if (arg == null) throw new ArgumentNullException(nameof(arg));
var user = arg.Item; var user = arg.Item;
user.MapFields(arg.Values); user.MapFields(arg.Values);
user.Parent = OrganizationUnits?.FirstOrDefault(x => x.Id == (Guid?)arg.Values[nameof(Node.ParentId)]); user.ParentId = (int?)arg.Values[nameof(Node.ParentId)];
var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false); var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false);
arg.Cancel = !result; arg.Cancel = !result;
} }