Robin Thoni 6 лет назад
Родитель
Сommit
830a82841a
59 измененных файлов: 2640 добавлений и 128 удалений
  1. 93
    10
      .idea/.idea.luticate2/.idea/contentModel.xml
  2. 87
    0
      Luticate2.Auth.ConsoleSample/Commands/CreateCommand.cs
  3. 116
    0
      Luticate2.Auth.ConsoleSample/Commands/ListCommand.cs
  4. 13
    0
      Luticate2.Auth.ConsoleSample/LuExtenstions.cs
  5. 9
    1
      Luticate2.Auth.ConsoleSample/Luticate2.Auth.ConsoleSample.csproj
  6. 69
    1
      Luticate2.Auth.ConsoleSample/Program.cs
  7. 61
    0
      Luticate2.Auth.Tests/Business/Fields/LuFieldDboTests.cs
  8. 135
    0
      Luticate2.Auth.Tests/Business/FieldsExpressions/LuFieldsExpressionsTests.cs
  9. 119
    0
      Luticate2.Auth.Tests/Business/LuExpressionUtilsTests.cs
  10. 19
    0
      Luticate2.Auth.Tests/Business/Pagination/LuFilterTests.cs
  11. 1
    1
      Luticate2.Auth.Tests/Luticate2.Auth.Tests.csproj
  12. 41
    0
      Luticate2.Auth.Tests/RandomTests.cs
  13. 0
    16
      Luticate2.Auth.Tests/UnitTest1.cs
  14. 37
    0
      Luticate2.Auth/Business/Auth/FieldsExpressions/LuFieldsExpressionsLuGroupDboLuGroups.cs
  15. 36
    0
      Luticate2.Auth/Business/Auth/FieldsExpressions/LuFieldsExpressionsLuMetadataDboLuMetadata.cs
  16. 85
    0
      Luticate2.Auth/Business/Auth/LuGroupsBusiness.cs
  17. 28
    0
      Luticate2.Auth/Business/Auth/PartialObjectCopier/LuPOCGroupsToDbo.cs
  18. 26
    0
      Luticate2.Auth/Business/Auth/PartialObjectCopier/LuPOCGroupsToModel.cs
  19. 27
    0
      Luticate2.Auth/Business/Auth/PartialObjectCopier/LuPOCObjectsMetadataToDbo.cs
  20. 223
    0
      Luticate2.Auth/Business/Crud/LuEfCrudBusiness.cs
  21. 186
    0
      Luticate2.Auth/Business/Fields/LuFieldsExtensions.cs
  22. 23
    0
      Luticate2.Auth/Business/Fields/LuPartialFieldsParser.cs
  23. 24
    0
      Luticate2.Auth/Business/FieldsExpressions/Basic/LuFieldsExpressionsString.cs
  24. 60
    0
      Luticate2.Auth/Business/FieldsExpressions/LuFieldsExpressions.cs
  25. 143
    0
      Luticate2.Auth/Business/LuExpressionUtils.cs
  26. 31
    0
      Luticate2.Auth/Business/Pagination/LuFilterParser.cs
  27. 58
    0
      Luticate2.Auth/Business/Pagination/LuOrderByParser.cs
  28. 114
    0
      Luticate2.Auth/Business/PartialObjectCopier/LuPartialObjectCopier.cs
  29. 11
    0
      Luticate2.Auth/Business/PartialObjectCopier/LuPartialObjectCopierExtensions.cs
  30. 147
    0
      Luticate2.Auth/Business/Serializers/PartialJson/LuJsonSerializerExtensions.cs
  31. 30
    0
      Luticate2.Auth/Business/Serializers/PartialJson/LuPartialJsonWriter.cs
  32. 30
    0
      Luticate2.Auth/Business/Serializers/PartialJson/LuSerializerContext.cs
  33. 0
    12
      Luticate2.Auth/Class1.cs
  34. 122
    0
      Luticate2.Auth/DataAccess/Luticate2DbContext.cs
  35. 19
    0
      Luticate2.Auth/DataAccess/Models/LuGroups.cs
  36. 15
    0
      Luticate2.Auth/DataAccess/Models/LuGroupsObjects.cs
  37. 21
    0
      Luticate2.Auth/DataAccess/Models/LuObjectsMetadata.cs
  38. 13
    0
      Luticate2.Auth/DataAccess/Models/LuUsers.cs
  39. 10
    0
      Luticate2.Auth/DataAccess/Models/TestTable.cs
  40. 133
    0
      Luticate2.Auth/DataAccess/Models/luticate2Context.cs
  41. 7
    0
      Luticate2.Auth/Dbo/Auth/LuGroupDbo.cs
  42. 11
    0
      Luticate2.Auth/Dbo/Auth/LuObjectDbo.cs
  43. 13
    0
      Luticate2.Auth/Dbo/Auth/LuObjectsMetadataDbo.cs
  44. 0
    7
      Luticate2.Auth/Dbo/Basic/LuAuthOptions.cs
  45. 50
    0
      Luticate2.Auth/Dbo/Fields/LuFieldDbo.cs
  46. 9
    0
      Luticate2.Auth/Dbo/Fields/LuPartialFieldsDbo.cs
  47. 1
    24
      Luticate2.Auth/Dbo/LuDboExtensions.cs
  48. 2
    47
      Luticate2.Auth/Dbo/Pagination/LuFilterDbo.cs
  49. 1
    1
      Luticate2.Auth/Dbo/Pagination/LuOrderByDbo.cs
  50. 11
    3
      Luticate2.Auth/Dbo/Pagination/LuOrderByFieldDbo.cs
  51. 7
    0
      Luticate2.Auth/Dbo/PartialObjectCopier/LuPartialObjectCopierOptions.cs
  52. 18
    0
      Luticate2.Auth/Interfaces/ILuCrud.cs
  53. 12
    0
      Luticate2.Auth/Interfaces/ILuFieldsExpressions.cs
  54. 14
    0
      Luticate2.Auth/Interfaces/ILuOrderByObjectType.cs
  55. 13
    0
      Luticate2.Auth/Interfaces/ILuPartialObjectCopier.cs
  56. 19
    3
      Luticate2.Auth/Luticate2.Auth.csproj
  57. 1
    1
      Luticate2.Mvc.Auth.WebApiSample/Luticate2.Mvc.Auth.WebApiSample.csproj
  58. 1
    1
      Luticate2.Mvc.Auth/Luticate2.Mvc.Auth.csproj
  59. 35
    0
      luticate2.sln.DotSettings.user

+ 93
- 10
.idea/.idea.luticate2/.idea/contentModel.xml Просмотреть файл

@@ -8,11 +8,69 @@
8 8
     <e p="$PROJECT_DIR$" t="IncludeFlat">
9 9
       <e p="Auth" t="Include" />
10 10
       <e p="Luticate2.Auth" t="IncludeRecursive">
11
-        <e p="Business" t="Include" />
12
-        <e p="Class1.cs" t="Include" />
11
+        <e p="Business" t="Include">
12
+          <e p="Auth" t="Include">
13
+            <e p="FieldsExpressions" t="Include">
14
+              <e p="LuFieldsExpressionsLuGroupDboLuGroups.cs" t="Include" />
15
+              <e p="LuFieldsExpressionsLuMetadataDboLuMetadata.cs" t="Include" />
16
+            </e>
17
+            <e p="LuGroupsBusiness.cs" t="Include" />
18
+            <e p="PartialObjectCopier" t="Include">
19
+              <e p="LuPOCGroupsToDbo.cs" t="Include" />
20
+              <e p="LuPOCGroupsToModel.cs" t="Include" />
21
+              <e p="LuPOCObjectsMetadataToDbo.cs" t="Include" />
22
+            </e>
23
+          </e>
24
+          <e p="Crud" t="Include">
25
+            <e p="LuEfCrudBusiness.cs" t="Include" />
26
+          </e>
27
+          <e p="Fields" t="Include">
28
+            <e p="LuFieldsExtensions.cs" t="Include" />
29
+            <e p="LuPartialFieldsParser.cs" t="Include" />
30
+          </e>
31
+          <e p="FieldsExpressions" t="Include">
32
+            <e p="Basic" t="Include">
33
+              <e p="LuFieldsExpressionsString.cs" t="Include" />
34
+            </e>
35
+            <e p="LuFieldsExpressions.cs" t="Include" />
36
+          </e>
37
+          <e p="LuExpressionUtils.cs" t="Include" />
38
+          <e p="Pagination" t="Include">
39
+            <e p="LuFilterParser.cs" t="Include" />
40
+            <e p="LuOrderByParser.cs" t="Include" />
41
+          </e>
42
+          <e p="PartialObjectCopier" t="Include">
43
+            <e p="LuPartialObjectCopier.cs" t="Include" />
44
+            <e p="LuPartialObjectCopierExtensions.cs" t="Include" />
45
+          </e>
46
+          <e p="Serializers" t="Include">
47
+            <e p="PartialJson" t="Include">
48
+              <e p="LuJsonSerializerExtensions.cs" t="Include" />
49
+              <e p="LuPartialJsonWriter.cs" t="Include" />
50
+              <e p="LuSerializerContext.cs" t="Include" />
51
+            </e>
52
+          </e>
53
+        </e>
54
+        <e p="DataAccess" t="Include">
55
+          <e p="Luticate2DbContext.cs" t="Include" />
56
+          <e p="Models" t="Include">
57
+            <e p="LuGroups.cs" t="Include" />
58
+            <e p="LuGroupsObjects.cs" t="Include" />
59
+            <e p="LuObjectsMetadata.cs" t="Include" />
60
+            <e p="LuUsers.cs" t="Include" />
61
+            <e p="TestTable.cs" t="Include" />
62
+            <e p="luticate2Context.cs" t="Include" />
63
+          </e>
64
+        </e>
13 65
         <e p="Dbo" t="Include">
14
-          <e p="Basic" t="Include">
15
-            <e p="LuAuthOptions.cs" t="Include" />
66
+          <e p="Auth" t="Include">
67
+            <e p="LuGroupDbo.cs" t="Include" />
68
+            <e p="LuObjectDbo.cs" t="Include" />
69
+            <e p="LuObjectsMetadataDbo.cs" t="Include" />
70
+          </e>
71
+          <e p="Fields" t="Include">
72
+            <e p="LuFieldDbo.cs" t="Include" />
73
+            <e p="LuPartialFieldsDbo.cs" t="Include" />
16 74
           </e>
17 75
           <e p="LuDboExtensions.cs" t="Include" />
18 76
           <e p="Pagination" t="Include">
@@ -22,6 +80,9 @@
22 80
             <e p="LuPaginatedDbo.cs" t="Include" />
23 81
             <e p="LuPaginatedParamsDbo.cs" t="Include" />
24 82
           </e>
83
+          <e p="PartialObjectCopier" t="Include">
84
+            <e p="LuPartialObjectCopierOptions.cs" t="Include" />
85
+          </e>
25 86
           <e p="Result" t="Include">
26 87
             <e p="LuResult.cs" t="Include" />
27 88
             <e p="LuStatus.cs" t="Include" />
@@ -31,36 +92,58 @@
31 92
           <e p="LuExceptionsExtensions.cs" t="Include" />
32 93
           <e p="LuResultException.cs" t="Include" />
33 94
         </e>
34
-        <e p="Interfaces" t="Include" />
95
+        <e p="Interfaces" t="Include">
96
+          <e p="ILuCrud.cs" t="Include" />
97
+          <e p="ILuFieldsExpressions.cs" t="Include" />
98
+          <e p="ILuOrderByObjectType.cs" t="Include" />
99
+          <e p="ILuPartialObjectCopier.cs" t="Include" />
100
+        </e>
35 101
         <e p="Luticate2.Auth.csproj" t="IncludeRecursive" />
36 102
         <e p="bin" t="ExcludeRecursive" />
37 103
         <e p="obj" t="ExcludeRecursive">
38 104
           <e p="Debug" t="Include">
39
-            <e p="netstandard2.0" t="Include">
105
+            <e p="netcoreapp2.1" t="Include">
40 106
               <e p="Luticate2.Auth.AssemblyInfo.cs" t="Include" />
41 107
             </e>
42 108
           </e>
43 109
         </e>
44 110
       </e>
45 111
       <e p="Luticate2.Auth.ConsoleSample" t="IncludeRecursive">
112
+        <e p="Commands" t="Include">
113
+          <e p="CreateCommand.cs" t="Include" />
114
+          <e p="ListCommand.cs" t="Include" />
115
+        </e>
116
+        <e p="LuExtenstions.cs" t="Include" />
46 117
         <e p="Luticate2.Auth.ConsoleSample.csproj" t="IncludeRecursive" />
47 118
         <e p="Program.cs" t="Include" />
48 119
         <e p="bin" t="ExcludeRecursive" />
49 120
         <e p="obj" t="ExcludeRecursive">
50 121
           <e p="Debug" t="Include">
51
-            <e p="netcoreapp2.0" t="Include">
122
+            <e p="netcoreapp2.1" t="Include">
52 123
               <e p="Luticate2.Auth.ConsoleSample.AssemblyInfo.cs" t="Include" />
53 124
             </e>
54 125
           </e>
55 126
         </e>
56 127
       </e>
57 128
       <e p="Luticate2.Auth.Tests" t="IncludeRecursive">
129
+        <e p="Business" t="Include">
130
+          <e p="Fields" t="Include">
131
+            <e p="LuFieldDboTests.cs" t="Include" />
132
+          </e>
133
+          <e p="FieldsExpressions" t="Include">
134
+            <e p="LuFieldsExpressionsTests.cs" t="Include" />
135
+          </e>
136
+          <e p="LuExpressionUtilsTests.cs" t="Include" />
137
+          <e p="Pagination" t="Include">
138
+            <e p="LuFilterTests.cs" t="Include" />
139
+          </e>
140
+        </e>
58 141
         <e p="Luticate2.Auth.Tests.csproj" t="IncludeRecursive" />
59
-        <e p="UnitTest1.cs" t="Include" />
142
+        <e p="RandomTests.cs" t="Include" />
60 143
         <e p="bin" t="ExcludeRecursive" />
61 144
         <e p="obj" t="ExcludeRecursive">
62 145
           <e p="Debug" t="Include">
63
-            <e p="netcoreapp2.0" t="Include">
146
+            <e p="netcoreapp2.1" t="Include">
64 147
               <e p="Luticate2.Auth.Tests.AssemblyInfo.cs" t="Include" />
65 148
               <e p="Luticate2.Auth.Tests.Program.cs" t="Include" />
66 149
             </e>
@@ -73,7 +156,7 @@
73 156
         <e p="bin" t="ExcludeRecursive" />
74 157
         <e p="obj" t="ExcludeRecursive">
75 158
           <e p="Debug" t="Include">
76
-            <e p="netstandard2.0" t="Include">
159
+            <e p="netcoreapp2.0" t="Include">
77 160
               <e p="Luticate2.Mvc.Auth.AssemblyInfo.cs" t="Include" />
78 161
             </e>
79 162
           </e>

+ 87
- 0
Luticate2.Auth.ConsoleSample/Commands/CreateCommand.cs Просмотреть файл

@@ -0,0 +1,87 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Threading;
4
+using System.Threading.Tasks;
5
+using Luticate2.Auth.Business.Auth;
6
+using Luticate2.Auth.Business.Fields;
7
+using Luticate2.Auth.Business.Serializers.PartialJson;
8
+using Luticate2.Auth.Dbo.Auth;
9
+using Microsoft.Extensions.DependencyInjection;
10
+using NClap.Metadata;
11
+using Newtonsoft.Json;
12
+
13
+namespace Luticate2.Auth.ConsoleSample.Commands
14
+{
15
+    public class CreateCommand : Command
16
+    {
17
+        [PositionalArgument(ArgumentFlags.Required, Position = 0, Description = "Items type to create")]
18
+        public string ItemType { get; set; }
19
+
20
+        [PositionalArgument(ArgumentFlags.Required, Position = 1, Description = "Items to create")]
21
+        public string Items { get; set; }
22
+
23
+        [NamedArgument(DefaultValue = "*")]
24
+        public string PartialResponse { get; set; }
25
+
26
+        [NamedArgument(DefaultValue = "*")]
27
+        public string PartialInput { get; set; }
28
+
29
+        [NamedArgument(DefaultValue = "specific")]
30
+        public string OutputType { get; set; }
31
+
32
+        public override Task<CommandResult> ExecuteAsync(CancellationToken cancel)
33
+        {
34
+            var partialResponseResult = LuPartialFieldsParser.Parse(PartialResponse);
35
+            if (!partialResponseResult)
36
+            {
37
+                partialResponseResult.WriteLineError();
38
+                return Task.FromResult(CommandResult.UsageError);
39
+            }
40
+            var partialResponse = partialResponseResult.Data;
41
+
42
+            var partialInputResult = LuPartialFieldsParser.Parse(PartialInput);
43
+            if (!partialInputResult)
44
+            {
45
+                partialInputResult.WriteLineError();
46
+                return Task.FromResult(CommandResult.UsageError);
47
+            }
48
+            var partialInput = partialInputResult.Data;
49
+
50
+            var business = Program.ServiceProvider.GetService<LuGroupsBusiness>();
51
+
52
+            var items = JsonConvert.DeserializeObject<IList<LuGroupDbo>>(Items);
53
+
54
+            var results = business.Create(partialResponse, partialInput, items);
55
+
56
+            if (results)
57
+            {
58
+                var jsonSettings = new JsonSerializerSettings
59
+                {
60
+                    Formatting = Formatting.None
61
+                };
62
+                foreach (var item in results.Data)
63
+                {
64
+                    if (OutputType == "specific")
65
+                    {
66
+                        Console.WriteLine($"{item.Id} {item.Name ?? "??"}");
67
+                    }
68
+                    else if (OutputType == "json-full")
69
+                    {
70
+                        Console.WriteLine(JsonConvert.SerializeObject(item, jsonSettings));
71
+                    }
72
+                    else if (OutputType == "json-partial")
73
+                    {
74
+                        Console.WriteLine(LuPartialJsonWriter.SerializeObject(item, partialResponse, jsonSettings));
75
+                    }
76
+                }
77
+            }
78
+            else
79
+            {
80
+                results.WriteLineError();
81
+                return Task.FromResult(CommandResult.RuntimeFailure);
82
+            }
83
+
84
+            return base.ExecuteAsync(cancel);
85
+        }
86
+    }
87
+}

+ 116
- 0
Luticate2.Auth.ConsoleSample/Commands/ListCommand.cs Просмотреть файл

@@ -0,0 +1,116 @@
1
+using System;
2
+using System.Diagnostics;
3
+using System.Threading;
4
+using System.Threading.Tasks;
5
+using Luticate2.Auth.Business.Auth;
6
+using Luticate2.Auth.Business.Pagination;
7
+using Luticate2.Auth.Business.Fields;
8
+using Luticate2.Auth.Business.Serializers.PartialJson;
9
+using Luticate2.Auth.DataAccess.Models;
10
+using Luticate2.Auth.Dbo.Auth;
11
+using Luticate2.Auth.Dbo.Pagination;
12
+using Microsoft.Extensions.DependencyInjection;
13
+using NClap.Metadata;
14
+using Newtonsoft.Json;
15
+
16
+namespace Luticate2.Auth.ConsoleSample.Commands
17
+{
18
+    public class ListCommand : Command
19
+    {
20
+        [PositionalArgument(ArgumentFlags.Optional, Position = 0, Description = "Items type to list")]
21
+        public string ItemType { get; set; }
22
+
23
+        [NamedArgument(DefaultValue = "*")]
24
+        public string PartialResponse { get; set; }
25
+
26
+        [NamedArgument(DefaultValue = "")]
27
+        public string Filter { get; set; }
28
+
29
+        [NamedArgument(DefaultValue = "id:asc")]
30
+        public string OrderBy { get; set; }
31
+
32
+        [NamedArgument(DefaultValue = "0")]
33
+        public int Page { get; set; }
34
+
35
+        [NamedArgument(DefaultValue = "10")]
36
+        public int PerPage { get; set; }
37
+
38
+        [NamedArgument(DefaultValue = "specific")]
39
+        public string OutputType { get; set; }
40
+
41
+        public override Task<CommandResult> ExecuteAsync(CancellationToken cancel)
42
+        {
43
+            if (ItemType == null)
44
+            {
45
+                Console.WriteLine("groups");
46
+            }
47
+            else
48
+            {
49
+                var partialResponseResult = LuPartialFieldsParser.Parse(PartialResponse);
50
+                if (!partialResponseResult)
51
+                {
52
+                    partialResponseResult.WriteLineError();
53
+                    return Task.FromResult(CommandResult.UsageError);
54
+                }
55
+                var partialResponse = partialResponseResult.Data;
56
+
57
+                var filterResult = LuFilterParser.Parse<LuGroups>(Filter);
58
+                if (!filterResult)
59
+                {
60
+                    filterResult.WriteLineError();
61
+                    return Task.FromResult(CommandResult.UsageError);
62
+                }
63
+                var filter = filterResult.Data;
64
+
65
+                var orderByResult = LuOrderByParser.Parse(OrderBy);
66
+                if (!orderByResult)
67
+                {
68
+                    orderByResult.WriteLineError();
69
+                    return Task.FromResult(CommandResult.UsageError);
70
+                }
71
+                var orderBy = orderByResult.Data;
72
+
73
+                var business = Program.ServiceProvider.GetService<LuGroupsBusiness>();
74
+                var stopWatch = Stopwatch.StartNew();
75
+                var results = business.Read(partialResponse, new LuPaginatedParamsDbo
76
+                {
77
+                    Filter = filter,
78
+                    OrderBy = orderBy,
79
+                    Page = Page,
80
+                    PerPage = PerPage
81
+                });
82
+                var elapsed = stopWatch.ElapsedMilliseconds;
83
+                if (results)
84
+                {
85
+                    var jsonSettings = new JsonSerializerSettings
86
+                    {
87
+                        Formatting = Formatting.None
88
+                    };
89
+                    Console.WriteLine($"Displaying {Page * PerPage + 1}-{(Page + 1) * PerPage} of {results.Data.Count} ({elapsed} ms)");
90
+                    foreach (var item in results.Data.Data)
91
+                    {
92
+                        if (OutputType == "specific")
93
+                        {
94
+                            Console.WriteLine($"{item.Id} {item.Name ?? "??"}");
95
+                        }
96
+                        else if (OutputType == "json-full")
97
+                        {
98
+                            Console.WriteLine(JsonConvert.SerializeObject(item, jsonSettings));
99
+                        }
100
+                        else if (OutputType == "json-partial")
101
+                        {
102
+                            Console.WriteLine(LuPartialJsonWriter.SerializeObject(item, partialResponse, jsonSettings));
103
+                        }
104
+                    }
105
+                }
106
+                else
107
+                {
108
+                    results.WriteLineError();
109
+                    return Task.FromResult(CommandResult.RuntimeFailure);
110
+                }
111
+            }
112
+
113
+            return Task.FromResult(CommandResult.Success);
114
+        }
115
+    }
116
+}

+ 13
- 0
Luticate2.Auth.ConsoleSample/LuExtenstions.cs Просмотреть файл

@@ -0,0 +1,13 @@
1
+using System;
2
+using Luticate2.Auth.Dbo.Result;
3
+
4
+namespace Luticate2.Auth.ConsoleSample
5
+{
6
+    public static class LuExtenstions
7
+    {
8
+        public static void WriteLineError<T>(this LuResult<T> result)
9
+        {
10
+            Console.WriteLine($"Error: {result.PublicDetails}\nPrivateDetails: {result.PrivateDetails}\nException: {result.Exception}");
11
+        }
12
+    }
13
+}

+ 9
- 1
Luticate2.Auth.ConsoleSample/Luticate2.Auth.ConsoleSample.csproj Просмотреть файл

@@ -1,9 +1,17 @@
1 1
 <Project Sdk="Microsoft.NET.Sdk">
2 2
   <PropertyGroup>
3 3
     <OutputType>Exe</OutputType>
4
-    <TargetFramework>netcoreapp2.0</TargetFramework>
4
+    <TargetFramework>netcoreapp2.1</TargetFramework>
5 5
   </PropertyGroup>
6 6
   <ItemGroup>
7 7
     <ProjectReference Include="..\Luticate2.Auth\Luticate2.Auth.csproj" />
8 8
   </ItemGroup>
9
+  <ItemGroup>
10
+    <PackageReference Include="NClap" Version="2.3.4" />
11
+  </ItemGroup>
12
+  <ItemGroup>
13
+    <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
14
+      <HintPath>..\..\..\..\.nuget\packages\newtonsoft.json\10.0.1\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath>
15
+    </Reference>
16
+  </ItemGroup>
9 17
 </Project>

+ 69
- 1
Luticate2.Auth.ConsoleSample/Program.cs Просмотреть файл

@@ -1,12 +1,80 @@
1 1
 using System;
2
+using Luticate2.Auth.Business.Auth;
3
+using Luticate2.Auth.Business.Auth.FieldsExpressions;
4
+using Luticate2.Auth.Business.Auth.PartialObjectCopier;
5
+using Luticate2.Auth.Business.FieldsExpressions;
6
+using Luticate2.Auth.Business.FieldsExpressions.Basic;
7
+//using Luticate2.Auth.Business.Pagination.OrderBy;
8
+//using Luticate2.Auth.Business.Pagination.OrderBy.Basic;
9
+using Luticate2.Auth.Business.PartialObjectCopier;
10
+using Luticate2.Auth.ConsoleSample.Commands;
11
+using Luticate2.Auth.DataAccess;
12
+using Luticate2.Auth.DataAccess.Models;
13
+using Luticate2.Auth.Dbo.Auth;
14
+using Luticate2.Auth.Interfaces;
15
+using Microsoft.EntityFrameworkCore;
16
+using Microsoft.Extensions.DependencyInjection;
17
+using NClap.Metadata;
18
+using NClap.Repl;
2 19
 
3 20
 namespace Luticate2.Auth.ConsoleSample
4 21
 {
22
+    enum CommandsEnum
23
+    {
24
+        [Command(typeof(ListCommand), Description = "Lists Luticate2 items", LongName = "ls", ShortName = "l")]
25
+        ListItems,
26
+
27
+        [Command(typeof(CreateCommand), Description = "Creates Luticate2 items", LongName = "create", ShortName = "c")]
28
+        CreateItems,
29
+
30
+        [Command(typeof(ExitCommand), Description = "Exits the shell")]
31
+        Exit
32
+    }
33
+    
5 34
     class Program
6 35
     {
36
+        public static IServiceProvider ServiceProvider;
37
+        
7 38
         static void Main(string[] args)
8 39
         {
9
-            Console.WriteLine(Class1.Method1("Hello World!"));
40
+            IServiceCollection services = new ServiceCollection();
41
+            
42
+            services.AddScoped<LuGroupsBusiness>();
43
+
44
+            services.AddSingleton<ILuPartialObjectCopier<LuObjectsMetadata, LuObjectsMetadataDbo>, LuPOCObjectsMetadataToDbo>();
45
+            services.AddSingleton<ILuPartialObjectCopier<LuGroups, LuGroupDbo>, LuPOCGroupsToDbo>();
46
+            services.AddSingleton<ILuPartialObjectCopier<LuGroupDbo, LuGroups>, LuPOCGroupsToModel>();
47
+
48
+
49
+            services.AddSingleton<ILuFieldsExpressions<LuObjectsMetadataDbo, LuObjectsMetadata>, LuFieldsExpressionsLuMetadataDboLuMetadata>();
50
+            services.AddSingleton<ILuFieldsExpressions<LuGroupDbo, LuGroups>, LuFieldsExpressionsLuGroupDboLuGroups>();
51
+
52
+            services.AddSingleton<ILuFieldsExpressions<string, string>, LuFieldsExpressionsString>();
53
+            services.AddSingleton<ILuFieldsExpressions<int, int>, LuFieldsExpressions<int, int>>();
54
+            services.AddSingleton<ILuFieldsExpressions<Guid, Guid>, LuFieldsExpressions<Guid, Guid>>();
55
+
56
+            services.AddSingleton<ILuFieldsExpressions<DateTime, DateTime>, LuFieldsExpressions<DateTime, DateTime>>();
57
+            services.AddSingleton<ILuFieldsExpressions<DateTimeOffset, DateTimeOffset>, LuFieldsExpressions<DateTimeOffset, DateTimeOffset>>();
58
+            services.AddSingleton<ILuFieldsExpressions<DateTime, DateTimeOffset>, LuFieldsExpressions<DateTime, DateTimeOffset>>();
59
+            services.AddSingleton<ILuFieldsExpressions<DateTimeOffset, DateTime>, LuFieldsExpressions<DateTimeOffset, DateTime>>();
60
+
61
+            services.AddSingleton<ILuFieldsExpressions<DateTime?, DateTime?>, LuFieldsExpressions<DateTime?, DateTime?>>();
62
+            services.AddSingleton<ILuFieldsExpressions<DateTimeOffset?, DateTimeOffset?>, LuFieldsExpressions<DateTimeOffset?, DateTimeOffset?>>();
63
+            services.AddSingleton<ILuFieldsExpressions<DateTime?, DateTimeOffset?>, LuFieldsExpressions<DateTime?, DateTimeOffset?>>();
64
+            services.AddSingleton<ILuFieldsExpressions<DateTimeOffset?, DateTime?>, LuFieldsExpressions<DateTimeOffset?, DateTime?>>();
65
+
66
+            services.AddDbContext<Luticate2DbContext>(options =>
67
+            {
68
+                options.UseNpgsql(@"Host=localhost;Database=luticate2;Username=dev;Password=dev");
69
+                options.UseInternalServiceProvider(new ServiceCollection()
70
+                    .AddEntityFrameworkNpgsql()
71
+                    .BuildServiceProvider());
72
+            }, ServiceLifetime.Transient);
73
+
74
+            ServiceProvider = services.BuildServiceProvider();
75
+            
76
+            var loop = new Loop(typeof(CommandsEnum));
77
+            loop.Execute();
10 78
         }
11 79
     }
12 80
 }

+ 61
- 0
Luticate2.Auth.Tests/Business/Fields/LuFieldDboTests.cs Просмотреть файл

@@ -0,0 +1,61 @@
1
+using System.Linq;
2
+using Luticate2.Auth.Business.Fields;
3
+using Luticate2.Auth.Dbo.Fields;
4
+using Xunit;
5
+
6
+namespace Luticate2.Auth.Tests.Business.Fields
7
+{
8
+    public class LuFieldDboTests
9
+    {
10
+        public class TestDbo1
11
+        {
12
+            public string MyString { get; set; }
13
+        }
14
+        
15
+        [Fact]
16
+        public void TestMake1()
17
+        {
18
+            var field1 = LuFieldDbo.Make<TestDbo1>(x => x.MyString.Length);
19
+            Assert.True(field1.Parts.SequenceEqual(new[] {"MyString", "Length"}));
20
+        }
21
+        
22
+        [Fact]
23
+        public void TestMake2()
24
+        {
25
+            var field1 = LuFieldDbo.Make(new[] {"MyString", "Length"});
26
+            Assert.True(field1.Parts.SequenceEqual(new[] {"MyString", "Length"}));
27
+        }
28
+        
29
+        [Fact]
30
+        public void TestMake3()
31
+        {
32
+            var field1 = LuFieldDbo.Make("MyString.Length");
33
+            Assert.True(field1.Parts.SequenceEqual(new[] {"MyString", "Length"}));
34
+        }
35
+        
36
+        [Fact]
37
+        public void TestMake4()
38
+        {
39
+            var field1 = LuFieldDbo.Make("MyString/Length");
40
+            Assert.True(field1.Parts.SequenceEqual(new[] {"MyString", "Length"}));
41
+        }
42
+
43
+        [Fact]
44
+        public void TestPop1()
45
+        {
46
+            var field1 = LuFieldDbo.Make<TestDbo1>(x => x.MyString.Length);
47
+            var field2 = field1.Pop();
48
+            Assert.True(field1.Parts.SequenceEqual(new[] {"Length"}));
49
+            Assert.True(field2.Parts.SequenceEqual(new[] {"Length"}));
50
+        }
51
+
52
+        [Fact]
53
+        public void TestPopped1()
54
+        {
55
+            var field1 = LuFieldDbo.Make<TestDbo1>(x => x.MyString.Length);
56
+            var field2 = field1.Popped();
57
+            Assert.True(field1.Parts.SequenceEqual(new[] {"MyString", "Length"}));
58
+            Assert.True(field2.Parts.SequenceEqual(new[] {"Length"}));
59
+        }
60
+    }
61
+}

+ 135
- 0
Luticate2.Auth.Tests/Business/FieldsExpressions/LuFieldsExpressionsTests.cs Просмотреть файл

@@ -0,0 +1,135 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Business;
4
+using Luticate2.Auth.Business.Fields;
5
+using Luticate2.Auth.Business.FieldsExpressions;
6
+using Luticate2.Auth.Business.FieldsExpressions.Basic;
7
+using Luticate2.Auth.Dbo;
8
+using Luticate2.Auth.Dbo.Fields;
9
+using Luticate2.Auth.Dbo.Result;
10
+using Luticate2.Auth.Interfaces;
11
+using Microsoft.Extensions.DependencyInjection;
12
+using Xunit;
13
+
14
+namespace Luticate2.Auth.Tests.Business.FieldsExpressions
15
+{
16
+    public class LuFieldsExpressionsTestDbo1TestModel1 : LuFieldsExpressions<TestDbo1, TestModel1>
17
+    {
18
+        public LuFieldsExpressionsTestDbo1TestModel1(IServiceProvider serviceProvider) : base(serviceProvider)
19
+        {
20
+        }
21
+
22
+        protected override LuResult<Expression<Func<TType1, object>>> GetExpressionInternal<TType1>(Expression<Func<TType1, TestModel1>> modelProperty, LuFieldDbo field)
23
+        {
24
+            if (field.StartsWith<TestDbo1>(x => x.MyInt))
25
+            {
26
+                return GetSubField<TType1, int, int>(modelProperty, field, x => x.MyInt);
27
+            }
28
+            else if (field.StartsWith<TestDbo1>(x => x.Metadata))
29
+            {
30
+                return GetSubField<TType1, MetadataDbo, MetadataModel>(modelProperty, field, x => x.MetadataModel);
31
+            }
32
+
33
+            return base.GetExpressionInternal(modelProperty, field);
34
+        }
35
+    }
36
+
37
+    public class LuFieldsExpressionsMetadataDboMetadataModel : LuFieldsExpressions<MetadataDbo, MetadataModel>
38
+    {
39
+        public LuFieldsExpressionsMetadataDboMetadataModel(IServiceProvider serviceProvider) : base(serviceProvider)
40
+        {
41
+        }
42
+
43
+        protected override LuResult<Expression<Func<TType1, object>>> GetExpressionInternal<TType1>(Expression<Func<TType1, MetadataModel>> modelProperty, LuFieldDbo field)
44
+        {
45
+            if (field.StartsWith<MetadataDbo>(x => x.Id))
46
+            {
47
+                return GetSubField<TType1, Guid, Guid>(modelProperty, field, x => x.Id);
48
+            }
49
+
50
+            return base.GetExpressionInternal(modelProperty, field);
51
+        }
52
+    }
53
+    
54
+    public class TestDbo1
55
+    {
56
+        public string MyString { get; set; }
57
+
58
+        public int MyInt { get; set; }
59
+
60
+        public MetadataDbo Metadata { get; set; }
61
+    }
62
+
63
+    public class MetadataDbo
64
+    {
65
+        public Guid Id { get; set; }
66
+
67
+        public DateTime CreatedAt { get; set; }
68
+    }
69
+    
70
+    public class TestModel1
71
+    {
72
+        public string MyString { get; set; }
73
+
74
+        public int MyInt { get; set; }
75
+
76
+        public MetadataModel MetadataModel { get; set; }
77
+    }
78
+
79
+    public class MetadataModel
80
+    {
81
+        public Guid Id { get; set; }
82
+
83
+        public DateTime CreatedAt { get; set; }
84
+    }
85
+    
86
+    public class LuFieldsExpressionsTests
87
+    {
88
+        public IServiceProvider GetServiceProvider()
89
+        {
90
+            var serviceCollection = new ServiceCollection();
91
+
92
+            serviceCollection.AddSingleton<ILuFieldsExpressions<TestDbo1, TestModel1>, LuFieldsExpressionsTestDbo1TestModel1>();
93
+            serviceCollection.AddSingleton<ILuFieldsExpressions<MetadataDbo, MetadataModel>, LuFieldsExpressionsMetadataDboMetadataModel>();
94
+            serviceCollection.AddSingleton<ILuFieldsExpressions<string, string>, LuFieldsExpressionsString>();
95
+            serviceCollection.AddSingleton<ILuFieldsExpressions<int, int>, LuFieldsExpressions<int, int>>();
96
+            serviceCollection.AddSingleton<ILuFieldsExpressions<Guid, Guid>, LuFieldsExpressions<Guid, Guid>>();
97
+
98
+            var serviceProvider = serviceCollection.BuildServiceProvider();
99
+            return serviceProvider;
100
+        }
101
+        
102
+        [Fact]
103
+        public void Test1()
104
+        {
105
+            var serviceProvider = GetServiceProvider();
106
+            var fieldExpression = serviceProvider.GetService<ILuFieldsExpressions<TestDbo1, TestModel1>>();
107
+            var exprResult = fieldExpression.GetExpression<TestModel1>(x => x, LuFieldDbo.Make("Metadata.Id"));
108
+            Assert.Equal(LuStatus.Success.ToInt(), exprResult.Status);
109
+            Assert.NotNull(exprResult.Data);
110
+            var operand = LuExpressionUtils.GetFromConvert(exprResult.Data);
111
+            var str = operand.ToString();
112
+            Assert.Equal("x.MetadataModel.Id", str);
113
+        }
114
+
115
+        [Fact]
116
+        public void TestError1()
117
+        {
118
+            var serviceProvider = GetServiceProvider();
119
+            var fieldExpression = serviceProvider.GetService<ILuFieldsExpressions<TestDbo1, TestModel1>>();
120
+            var exprResult = fieldExpression.GetExpression<TestModel1>(x => x, LuFieldDbo.Make("Metadata.Id.NxField"));
121
+            Assert.Equal(LuStatus.InputError.ToInt(), exprResult.Status);
122
+            Assert.Null(exprResult.Data);
123
+        }
124
+
125
+        [Fact]
126
+        public void TestError2()
127
+        {
128
+            var serviceProvider = GetServiceProvider();
129
+            var fieldExpression = serviceProvider.GetService<ILuFieldsExpressions<TestDbo1, TestModel1>>();
130
+            var exprResult = fieldExpression.GetExpression<TestModel1>(x => x, LuFieldDbo.Make("Metadata.*"));
131
+            Assert.Equal(LuStatus.InputError.ToInt(), exprResult.Status);
132
+            Assert.Null(exprResult.Data);
133
+        }
134
+    }
135
+}

+ 119
- 0
Luticate2.Auth.Tests/Business/LuExpressionUtilsTests.cs Просмотреть файл

@@ -0,0 +1,119 @@
1
+using System.Linq;
2
+using Luticate2.Auth.Business;
3
+using Xunit;
4
+
5
+namespace Luticate2.Auth.Tests.Business
6
+{
7
+    public class TestDbo1
8
+    {
9
+        public string MyString { get; set; }
10
+
11
+        public TestDbo2 TestDbo2 { get; set; }
12
+    }
13
+
14
+    public class TestDbo2
15
+    {
16
+        public string MyOtherString { get; set; }
17
+        
18
+        public int MyInt { get; set; }
19
+
20
+        public TestDbo2 RecursiveObject { get; set; }
21
+    }
22
+
23
+    public class LuExpressionUtilsTests
24
+    {
25
+        [Fact]
26
+        public void GetSingleMemberFromExpression1()
27
+        {
28
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression<TestDbo1, string>(x => x.MyString);
29
+            Assert.NotNull(memberInfo);
30
+            Assert.Equal("MyString", memberInfo.Name);
31
+        }
32
+        
33
+        [Fact]
34
+        public void GetSingleMemberFromExpression2()
35
+        {
36
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression<TestDbo1, TestDbo2>(x => x.TestDbo2);
37
+            Assert.NotNull(memberInfo);
38
+            Assert.Equal("TestDbo2", memberInfo.Name);
39
+        }
40
+        
41
+        [Fact]
42
+        public void GetSingleMemberFromExpression3()
43
+        {
44
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression<TestDbo1, TestDbo1>(x => x);
45
+            Assert.Null(memberInfo);
46
+        }
47
+        
48
+        [Fact]
49
+        public void GetSingleMemberFromExpression4()
50
+        {
51
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression<TestDbo1, int>(x => 42);
52
+            Assert.Null(memberInfo);
53
+        }
54
+        
55
+        [Fact]
56
+        public void GetSingleMemberFromExpression5()
57
+        {
58
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression<TestDbo1, int>(x => x.TestDbo2.MyInt);
59
+            Assert.Null(memberInfo);
60
+        }
61
+        
62
+        [Fact]
63
+        public void GetSingleMemberFromExpression6()
64
+        {
65
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression<TestDbo1, int>(x => x.TestDbo2.RecursiveObject.MyInt);
66
+            Assert.Null(memberInfo);
67
+        }
68
+
69
+        [Fact]
70
+        public void GetMembersFromExpression1()
71
+        {
72
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression<TestDbo1, string>(x => x.MyString);
73
+            Assert.NotNull(memberInfo);
74
+            var memberInfosString = string.Join(".", memberInfo.Select(x => x.Name));
75
+            Assert.Equal("MyString", memberInfosString);
76
+        }
77
+
78
+        [Fact]
79
+        public void GetMembersFromExpression2()
80
+        {
81
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression<TestDbo1, TestDbo2>(x => x.TestDbo2);
82
+            Assert.NotNull(memberInfo);
83
+            var memberInfosString = string.Join(".", memberInfo.Select(x => x.Name));
84
+            Assert.Equal("TestDbo2", memberInfosString);
85
+        }
86
+
87
+        [Fact]
88
+        public void GetMembersFromExpression3()
89
+        {
90
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression<TestDbo1, TestDbo1>(x => x);
91
+            Assert.Null(memberInfo);
92
+        }
93
+
94
+        [Fact]
95
+        public void GetMembersFromExpression4()
96
+        {
97
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression<TestDbo1, int>(x => 42);
98
+            Assert.Null(memberInfo);
99
+        }
100
+
101
+        [Fact]
102
+        public void GetMembersFromExpression5()
103
+        {
104
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression<TestDbo1, int>(x => x.TestDbo2.MyInt);
105
+            Assert.NotNull(memberInfo);
106
+            var memberInfosString = string.Join(".", memberInfo.Select(x => x.Name));
107
+            Assert.Equal("TestDbo2.MyInt", memberInfosString);
108
+        }
109
+
110
+        [Fact]
111
+        public void GetMembersFromExpression6()
112
+        {
113
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression<TestDbo1, int>(x => x.TestDbo2.RecursiveObject.MyInt);
114
+            Assert.NotNull(memberInfo);
115
+            var memberInfosString = string.Join(".", memberInfo.Select(x => x.Name));
116
+            Assert.Equal("TestDbo2.RecursiveObject.MyInt", memberInfosString);
117
+        }
118
+    }
119
+}

+ 19
- 0
Luticate2.Auth.Tests/Business/Pagination/LuFilterTests.cs Просмотреть файл

@@ -0,0 +1,19 @@
1
+using Luticate2.Auth.Business.Pagination;
2
+using Luticate2.Auth.Dbo;
3
+using Luticate2.Auth.Dbo.Auth;
4
+using Luticate2.Auth.Dbo.Result;
5
+using Xunit;
6
+
7
+namespace Luticate2.Auth.Tests.Business.Pagination
8
+{
9
+    public class LuFilterTests
10
+    {
11
+        [Fact]
12
+        public void Test1()
13
+        {
14
+            var filterResult = LuFilterParser.Parse<LuGroupDbo>("x.Name.Contains(\"test\")");
15
+            Assert.Equal(LuStatus.Success.ToInt(), filterResult.Status);
16
+            Assert.NotNull(filterResult.Data);
17
+        }
18
+    }
19
+}

+ 1
- 1
Luticate2.Auth.Tests/Luticate2.Auth.Tests.csproj Просмотреть файл

@@ -1,6 +1,6 @@
1 1
 <Project Sdk="Microsoft.NET.Sdk">
2 2
   <PropertyGroup>
3
-    <TargetFramework>netcoreapp2.0</TargetFramework>
3
+    <TargetFramework>netcoreapp2.1</TargetFramework>
4 4
     <IsPackable>false</IsPackable>
5 5
   </PropertyGroup>
6 6
   <ItemGroup>

+ 41
- 0
Luticate2.Auth.Tests/RandomTests.cs Просмотреть файл

@@ -0,0 +1,41 @@
1
+using System.Linq;
2
+using Luticate2.Auth.DataAccess;
3
+using Luticate2.Auth.DataAccess.Models;
4
+using Microsoft.EntityFrameworkCore;
5
+using Xunit;
6
+
7
+namespace Luticate2.Auth.Tests
8
+{
9
+    public class RandomTests
10
+    {
11
+        [Fact]
12
+        public void Test1()
13
+        {
14
+            var dbContext = new luticate2Context();
15
+            var items = dbContext.LuGroups.Where(groups => groups.LuGroupsObjects.Any(x => x.Priority == 0));
16
+            var list = items.ToList();
17
+            Assert.NotNull(list);
18
+            Assert.Equal(1, list.Count);
19
+        }
20
+
21
+        [Fact]
22
+        public void Test2()
23
+        {
24
+            var dbContext = new luticate2Context();
25
+            var items = dbContext.LuGroups.OrderBy(x => x.Id).Where(groups => groups.LuGroupsObjects.Any(x => x.Priority == 0));
26
+            var list = items.ToList();
27
+            Assert.NotNull(list);
28
+            Assert.Equal(1, list.Count);
29
+        }
30
+
31
+        [Fact]
32
+        public void Test3()
33
+        {
34
+            var dbContext = new luticate2Context();
35
+            var items = dbContext.LuGroups.OrderBy(x => x.Id);
36
+            var list = items.ToList();
37
+            Assert.NotNull(list);
38
+            Assert.Equal(2, list.Count);
39
+        }
40
+    }
41
+}

+ 0
- 16
Luticate2.Auth.Tests/UnitTest1.cs Просмотреть файл

@@ -1,16 +0,0 @@
1
-using System;
2
-using Xunit;
3
-
4
-namespace Luticate2.Auth.Tests
5
-{
6
-    public class UnitTest1
7
-    {
8
-        [Fact]
9
-        public void Test1()
10
-        {
11
-            string expected = "testValue 0";
12
-            string actual = Class1.Method1("0");
13
-            Assert.Equal(expected, actual);
14
-        }
15
-    }
16
-}

+ 37
- 0
Luticate2.Auth/Business/Auth/FieldsExpressions/LuFieldsExpressionsLuGroupDboLuGroups.cs Просмотреть файл

@@ -0,0 +1,37 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Business.Fields;
4
+using Luticate2.Auth.Business.FieldsExpressions;
5
+using Luticate2.Auth.DataAccess.Models;
6
+using Luticate2.Auth.Dbo.Auth;
7
+using Luticate2.Auth.Dbo.Fields;
8
+using Luticate2.Auth.Dbo.Result;
9
+
10
+namespace Luticate2.Auth.Business.Auth.FieldsExpressions
11
+{
12
+    public class LuFieldsExpressionsLuGroupDboLuGroups : LuFieldsExpressions<LuGroupDbo, LuGroups>
13
+    {
14
+        public LuFieldsExpressionsLuGroupDboLuGroups(IServiceProvider serviceProvider) : base(serviceProvider)
15
+        {
16
+        }
17
+
18
+        protected override LuResult<Expression<Func<TType1, object>>> GetExpressionInternal<TType1>(
19
+            Expression<Func<TType1, LuGroups>> modelProperty, LuFieldDbo field)
20
+        {
21
+            if (field.StartsWith<LuGroupDbo>(x => x.Id))
22
+            {
23
+                return GetSubField<TType1, Guid, Guid>(modelProperty, field, x => x.Id);
24
+            }
25
+            else if (field.StartsWith<LuGroupDbo>(x => x.Name))
26
+            {
27
+                return GetSubField<TType1, string, string>(modelProperty, field, x => x.Name);
28
+            }
29
+            else if (field.StartsWith<LuGroupDbo>(x => x.Metadata))
30
+            {
31
+                return GetSubField<TType1, LuObjectsMetadataDbo, LuObjectsMetadata>(modelProperty, field, x => x.IdNavigation);
32
+            }
33
+
34
+            return base.GetExpressionInternal(modelProperty, field);
35
+        }
36
+    }
37
+}

+ 36
- 0
Luticate2.Auth/Business/Auth/FieldsExpressions/LuFieldsExpressionsLuMetadataDboLuMetadata.cs Просмотреть файл

@@ -0,0 +1,36 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Business.Fields;
4
+using Luticate2.Auth.Business.FieldsExpressions;
5
+using Luticate2.Auth.DataAccess.Models;
6
+using Luticate2.Auth.Dbo.Auth;
7
+using Luticate2.Auth.Dbo.Fields;
8
+using Luticate2.Auth.Dbo.Result;
9
+
10
+namespace Luticate2.Auth.Business.Auth.FieldsExpressions
11
+{
12
+    public class LuFieldsExpressionsLuMetadataDboLuMetadata : LuFieldsExpressions<LuObjectsMetadataDbo, LuObjectsMetadata>
13
+    {
14
+        public LuFieldsExpressionsLuMetadataDboLuMetadata(IServiceProvider serviceProvider) : base(serviceProvider)
15
+        {
16
+        }
17
+
18
+        protected override LuResult<Expression<Func<TType1, object>>> GetExpressionInternal<TType1>(Expression<Func<TType1, LuObjectsMetadata>> modelProperty, LuFieldDbo field)
19
+        {
20
+            if (field.StartsWith<LuObjectsMetadataDbo>(x => x.Id))
21
+            {
22
+                return GetSubField<TType1, Guid, Guid>(modelProperty, field, x => x.Id);
23
+            }
24
+            if (field.StartsWith<LuObjectsMetadataDbo>(x => x.CreatedAt))
25
+            {
26
+                return GetSubField<TType1, DateTime, DateTimeOffset>(modelProperty, field, x => x.CreatedAt);
27
+            }
28
+            if (field.StartsWith<LuObjectsMetadataDbo>(x => x.UpdatedAt))
29
+            {
30
+                return GetSubField<TType1, DateTime?, DateTimeOffset?>(modelProperty, field, x => x.UpdatedAt);
31
+            }
32
+
33
+            return base.GetExpressionInternal(modelProperty, field);
34
+        }
35
+    }
36
+}

+ 85
- 0
Luticate2.Auth/Business/Auth/LuGroupsBusiness.cs Просмотреть файл

@@ -0,0 +1,85 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Security.Cryptography.X509Certificates;
5
+using Luticate2.Auth.Business.Crud;
6
+using Luticate2.Auth.Business.Fields;
7
+using Luticate2.Auth.DataAccess;
8
+using Luticate2.Auth.DataAccess.Models;
9
+using Luticate2.Auth.Dbo.Auth;
10
+using Luticate2.Auth.Dbo.Fields;
11
+using Luticate2.Auth.Dbo.Pagination;
12
+using Luticate2.Auth.Dbo.Result;
13
+using Microsoft.EntityFrameworkCore;
14
+
15
+namespace Luticate2.Auth.Business.Auth
16
+{
17
+    public class LuGroupsBusiness : LuEfCrudBusiness<LuGroupDbo, LuGroups, Luticate2DbContext>
18
+    {
19
+        public LuGroupsBusiness(IServiceProvider serviceProvider) : base(serviceProvider)
20
+        {
21
+        }
22
+
23
+        protected override LuResult<IQueryable<LuGroups>> Include(LuPartialFieldsDbo partialResponse, IQueryable<LuGroups> queryable)
24
+        {
25
+            var included = queryable;
26
+            if (partialResponse.Fields.IsIncluded<LuGroupDbo>(x => x.Metadata))
27
+            {
28
+                included = included.Include(x => x.IdNavigation);
29
+            }
30
+
31
+            return LuResult<IQueryable<LuGroups>>.Ok(included);
32
+        }
33
+
34
+//        protected override LuResult<IQueryable<LuGroups>> Filter(LuFilterDbo filter, IQueryable<LuGroups> queryable)
35
+//        {
36
+//            return LuResult<IQueryable<LuGroups>>.Ok(queryable.Where(groups => groups.LuGroupsObjects.Any(objects => objects.Priority == 0)));
37
+//        }
38
+
39
+        public override LuResult<IList<LuGroupDbo>> Create(LuPartialFieldsDbo partialResponse,
40
+            LuPartialFieldsDbo partialInput, IEnumerable<LuGroupDbo> dbos)
41
+        {
42
+            var addedDbos = new List<LuGroupDbo>();
43
+            var addedModels = new List<LuGroups>();
44
+            var createResult = Execute((context, set) =>
45
+            {
46
+                foreach (var dbo in dbos)
47
+                {
48
+                    var model = new LuGroups();
49
+                    var addResult = ConvertDboToModel(partialInput, dbo, model);
50
+                    if (!addResult)
51
+                    {
52
+                        return addResult.To<bool>();
53
+                    }
54
+                    model.IdNavigation = new LuObjectsMetadata();
55
+                    set.Add(model);
56
+                    addedModels.Add(model);
57
+                }
58
+
59
+                context.SaveChanges();
60
+
61
+                return LuResult<bool>.Ok(true);
62
+            });
63
+
64
+            if (!createResult)
65
+            {
66
+                return createResult.To<IList<LuGroupDbo>>();
67
+            }
68
+
69
+            var ids = addedModels.Select(x => x.Id);
70
+
71
+            foreach (var addedModel in addedModels)
72
+            {
73
+                var addedDbo = new LuGroupDbo();
74
+                var convertResult = ConvertModelToDbo(partialResponse, addedModel, addedDbo);
75
+                if (!convertResult)
76
+                {
77
+                    return convertResult.To<IList<LuGroupDbo>>();
78
+                }
79
+                addedDbos.Add(addedDbo);
80
+            }
81
+
82
+            return LuResult<IList<LuGroupDbo>>.Ok(addedDbos);
83
+        }
84
+    }
85
+}

+ 28
- 0
Luticate2.Auth/Business/Auth/PartialObjectCopier/LuPOCGroupsToDbo.cs Просмотреть файл

@@ -0,0 +1,28 @@
1
+using System;
2
+using System.Linq;
3
+using Luticate2.Auth.Business.PartialObjectCopier;
4
+using Luticate2.Auth.DataAccess.Models;
5
+using Luticate2.Auth.Dbo.Auth;
6
+using Luticate2.Auth.Dbo.Fields;
7
+using Luticate2.Auth.Dbo.PartialObjectCopier;
8
+using Luticate2.Auth.Dbo.Result;
9
+
10
+namespace Luticate2.Auth.Business.Auth.PartialObjectCopier
11
+{
12
+    public class LuPOCGroupsToDbo : LuPartialObjectCopier<LuGroups, LuGroupDbo>
13
+    {
14
+        public LuPOCGroupsToDbo(IServiceProvider serviceProvider) : base(serviceProvider)
15
+        {
16
+        }
17
+
18
+        public override LuResult<LuGroupDbo> Copy(LuFieldDbo path, LuPartialFieldsDbo fields, LuGroups modelFrom,
19
+            LuGroupDbo dboTo, LuPartialObjectCopierOptions options)
20
+        {
21
+            MayCopy(path, fields, dboTo, dbo => dbo.Id, () => modelFrom.Id);
22
+            MayCopySubProperty(path, fields, modelFrom, dboTo, x => x.IdNavigation, x => x.Metadata, options);
23
+            MayCopy(path, fields, dboTo, dbo => dbo.Name, () => modelFrom.Name);
24
+
25
+            return LuResult<LuGroupDbo>.Ok(dboTo);
26
+        }
27
+    }
28
+}

+ 26
- 0
Luticate2.Auth/Business/Auth/PartialObjectCopier/LuPOCGroupsToModel.cs Просмотреть файл

@@ -0,0 +1,26 @@
1
+using System;
2
+using Luticate2.Auth.Business.PartialObjectCopier;
3
+using Luticate2.Auth.DataAccess.Models;
4
+using Luticate2.Auth.Dbo.Auth;
5
+using Luticate2.Auth.Dbo.Fields;
6
+using Luticate2.Auth.Dbo.PartialObjectCopier;
7
+using Luticate2.Auth.Dbo.Result;
8
+
9
+namespace Luticate2.Auth.Business.Auth.PartialObjectCopier
10
+{
11
+    public class LuPOCGroupsToModel : LuPartialObjectCopier<LuGroupDbo, LuGroups>
12
+    {
13
+        public LuPOCGroupsToModel(IServiceProvider serviceProvider) : base(serviceProvider)
14
+        {
15
+        }
16
+
17
+        public override LuResult<LuGroups> Copy(LuFieldDbo path, LuPartialFieldsDbo fields, LuGroupDbo dboFrom, LuGroups modelTo,
18
+            LuPartialObjectCopierOptions options)
19
+        {
20
+            MayCopy(path, fields, modelTo, model => model.Id, () => dboFrom.Id);
21
+            MayCopy(path, fields, modelTo, model => model.Name, () => dboFrom.Name);
22
+
23
+            return LuResult<LuGroups>.Ok(modelTo);
24
+        }
25
+    }
26
+}

+ 27
- 0
Luticate2.Auth/Business/Auth/PartialObjectCopier/LuPOCObjectsMetadataToDbo.cs Просмотреть файл

@@ -0,0 +1,27 @@
1
+using System;
2
+using Luticate2.Auth.Business.PartialObjectCopier;
3
+using Luticate2.Auth.DataAccess.Models;
4
+using Luticate2.Auth.Dbo.Auth;
5
+using Luticate2.Auth.Dbo.Fields;
6
+using Luticate2.Auth.Dbo.PartialObjectCopier;
7
+using Luticate2.Auth.Dbo.Result;
8
+
9
+namespace Luticate2.Auth.Business.Auth.PartialObjectCopier
10
+{
11
+    public class LuPOCObjectsMetadataToDbo : LuPartialObjectCopier<LuObjectsMetadata, LuObjectsMetadataDbo>
12
+    {
13
+        public LuPOCObjectsMetadataToDbo(IServiceProvider serviceProvider) : base(serviceProvider)
14
+        {
15
+        }
16
+
17
+        public override LuResult<LuObjectsMetadataDbo> Copy(LuFieldDbo path, LuPartialFieldsDbo fields, LuObjectsMetadata modelFrom, LuObjectsMetadataDbo dboTo,
18
+            LuPartialObjectCopierOptions options)
19
+        {
20
+            MayCopy(path, fields, dboTo, dbo => dbo.Id, () => modelFrom.Id);
21
+            MayCopy(path, fields, dboTo, dbo => dbo.CreatedAt, () => modelFrom.CreatedAt);
22
+            MayCopy(path, fields, dboTo, dbo => dbo.UpdatedAt, () => modelFrom.UpdatedAt);
23
+
24
+            return LuResult<LuObjectsMetadataDbo>.Ok(dboTo);
25
+        }
26
+    }
27
+}

+ 223
- 0
Luticate2.Auth/Business/Crud/LuEfCrudBusiness.cs Просмотреть файл

@@ -0,0 +1,223 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Linq.Expressions;
5
+using Luticate2.Auth.Dbo;
6
+using Luticate2.Auth.Dbo.Fields;
7
+using Luticate2.Auth.Dbo.Pagination;
8
+using Luticate2.Auth.Dbo.PartialObjectCopier;
9
+using Luticate2.Auth.Dbo.Result;
10
+using Luticate2.Auth.Interfaces;
11
+using Microsoft.EntityFrameworkCore;
12
+using Microsoft.Extensions.DependencyInjection;
13
+
14
+namespace Luticate2.Auth.Business.Crud
15
+{
16
+    public class LuEfCrudBusiness<TDbo, TModel, TDbContext> : ILuCrud<TDbo>
17
+        where TModel : class
18
+        where TDbContext : DbContext
19
+        where TDbo : new()
20
+    {
21
+        protected IServiceProvider ServiceProvider { get; }
22
+
23
+        public LuEfCrudBusiness(IServiceProvider serviceProvider)
24
+        {
25
+            ServiceProvider = serviceProvider;
26
+        }
27
+
28
+        protected virtual LuResult<TModel> ConvertDboToModel(LuPartialFieldsDbo partialInput, TDbo dbo, TModel model)
29
+        {
30
+            var copier = ServiceProvider.GetService<ILuPartialObjectCopier<TDbo, TModel>>();
31
+            if (copier == null)
32
+            {
33
+                return LuResult<TModel>.Error(LuStatus.InternalError.ToInt(), $"Could not get service: ILuPartialObjectCopier<{typeof(TDbo).Name}, {typeof(TModel).Name}>");
34
+            }
35
+            var result = copier.Copy(partialInput, dbo, model, new LuPartialObjectCopierOptions());
36
+            return result;
37
+        }
38
+
39
+        protected virtual LuResult<TDbo> ConvertModelToDbo(LuPartialFieldsDbo partialResponse, TModel model, TDbo dbo)
40
+        {
41
+            var copier = ServiceProvider.GetService<ILuPartialObjectCopier<TModel, TDbo>>();
42
+            if (copier == null)
43
+            {
44
+                return LuResult<TDbo>.Error(LuStatus.InternalError.ToInt(), $"Could not get service: ILuPartialObjectCopier<{typeof(TModel).Name}, {typeof(TDbo).Name}>");
45
+            }
46
+            var result = copier.Copy(partialResponse, model, dbo, new LuPartialObjectCopierOptions());
47
+            return result;
48
+        }
49
+
50
+        protected virtual LuResult<T> HandleError<T>(Exception e)
51
+        {
52
+            return LuResult<T>.Error(LuStatus.DbError.ToInt(), e);
53
+        }
54
+
55
+        protected LuResult<T> Execute<T>(Func<TDbContext, DbSet<TModel>, LuResult<T>> action)
56
+        {
57
+            try
58
+            {
59
+                using (var db = ServiceProvider.GetService<TDbContext>())
60
+                {
61
+                    return action(db, db.Set<TModel>());
62
+                }
63
+            }
64
+            catch (Exception e)
65
+            {
66
+                var result = HandleError<T>(e);
67
+                return result;
68
+            }
69
+        }
70
+
71
+        protected virtual LuResult<IQueryable<TModel>> Include(LuPartialFieldsDbo partialResponse, IQueryable<TModel> queryable)
72
+        {
73
+            return LuResult<IQueryable<TModel>>.Ok(queryable);
74
+        }
75
+
76
+        protected virtual LuResult<IQueryable<TModel>> Filter(LuFilterDbo filter, IQueryable<TModel> queryable)
77
+        {
78
+            return LuResult<IQueryable<TModel>>.Ok(queryable.Where((Expression<Func<TModel, bool>>) filter.Expression));
79
+        }
80
+
81
+        protected IQueryable<TModel> ConvertAndOrderByQueryable<T>(Expression<Func<TModel, object>> exp,
82
+            LuOrderByFieldDbo orderByfield, IQueryable<TModel> queryable, Expression expressionNoConvert)
83
+        {
84
+            var ordered = queryable as IOrderedQueryable<TModel>;
85
+            var expType = expressionNoConvert.Type;
86
+            var type = typeof(T);
87
+            if (type.IsAssignableFrom(expType))
88
+            {
89
+                var expLambda = Expression.Lambda<Func<TModel, T>>(expressionNoConvert, exp.Parameters);
90
+                if (ordered != null)
91
+                {
92
+                    ordered = orderByfield.Asc ? ordered.ThenBy(expLambda) : ordered.ThenByDescending(expLambda);
93
+                }
94
+                else
95
+                {
96
+                    ordered = orderByfield.Asc ? queryable.OrderBy(expLambda) : queryable.OrderByDescending(expLambda);
97
+                }
98
+            }
99
+
100
+            return ordered ?? queryable;
101
+        }
102
+
103
+        protected virtual LuResult<IQueryable<TModel>> OrderByField(LuOrderByFieldDbo orderByfield, IQueryable<TModel> queryable)
104
+        {
105
+            var expressionBuilder = ServiceProvider.GetService<ILuFieldsExpressions<TDbo, TModel>>();
106
+            var expressionResult = expressionBuilder.GetExpression<TModel>(x => x, orderByfield.Field);
107
+            if (!expressionResult)
108
+            {
109
+                return expressionResult.To<IQueryable<TModel>>();
110
+            }
111
+
112
+            var expression = expressionResult.Data;
113
+            var expressionNoConvert = LuExpressionUtils.GetFromConvert(expression);
114
+
115
+            var ordered = ConvertAndOrderByQueryable<bool>(expression, orderByfield, queryable, expressionNoConvert);
116
+            ordered = ConvertAndOrderByQueryable<byte>(expression, orderByfield, ordered, expressionNoConvert);
117
+            ordered = ConvertAndOrderByQueryable<DateTime>(expression, orderByfield, ordered, expressionNoConvert);
118
+            ordered = ConvertAndOrderByQueryable<DateTimeOffset>(expression, orderByfield, ordered, expressionNoConvert);
119
+            ordered = ConvertAndOrderByQueryable<decimal>(expression, orderByfield, ordered, expressionNoConvert);
120
+            ordered = ConvertAndOrderByQueryable<double>(expression, orderByfield, ordered, expressionNoConvert);
121
+            ordered = ConvertAndOrderByQueryable<float>(expression, orderByfield, ordered, expressionNoConvert);
122
+            ordered = ConvertAndOrderByQueryable<Guid>(expression, orderByfield, ordered, expressionNoConvert);
123
+            ordered = ConvertAndOrderByQueryable<short>(expression, orderByfield, ordered, expressionNoConvert);
124
+            ordered = ConvertAndOrderByQueryable<int>(expression, orderByfield, ordered, expressionNoConvert);
125
+            ordered = ConvertAndOrderByQueryable<long>(expression, orderByfield, ordered, expressionNoConvert);
126
+            ordered = ConvertAndOrderByQueryable<char>(expression, orderByfield, ordered, expressionNoConvert);
127
+            ordered = ConvertAndOrderByQueryable<string>(expression, orderByfield, ordered, expressionNoConvert);
128
+            
129
+            return LuResult<IQueryable<TModel>>.Ok(ordered);
130
+        }
131
+
132
+        protected virtual LuResult<IQueryable<TModel>> OrderBy(LuOrderByDbo orderBy, IQueryable<TModel> queryable)
133
+        {
134
+            var ordered = queryable;
135
+            foreach (var field in orderBy.OrderByFields)
136
+            {
137
+                var orderedResult = OrderByField(field, ordered);
138
+                if (!orderedResult)
139
+                {
140
+                    return orderedResult.To<IQueryable<TModel>>();
141
+                }
142
+
143
+                ordered = orderedResult.Data;
144
+            }
145
+
146
+            return LuResult<IQueryable<TModel>>.Ok(ordered ?? queryable);
147
+        }
148
+
149
+        protected virtual LuResult<IQueryable<TModel>> Paginate(int page, int perPage, IQueryable<TModel> queryable)
150
+        {
151
+            var paginated = queryable.Skip(page * perPage).Take(perPage);
152
+            return LuResult<IQueryable<TModel>>.Ok(paginated);
153
+        }
154
+
155
+        public virtual LuResult<IList<TDbo>> Create(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
156
+        {
157
+            throw new NotImplementedException();
158
+        }
159
+
160
+        public virtual LuResult<LuPaginatedDbo<TDbo>> Read(LuPartialFieldsDbo partialResponse, LuPaginatedParamsDbo paginationParams)
161
+        {
162
+            var result = Execute((context, set) =>
163
+            {
164
+                var includeResult = Include(partialResponse, set);
165
+                if (!includeResult)
166
+                {
167
+                    return includeResult.To<LuPaginatedDbo<TDbo>>();
168
+                }
169
+
170
+                var included = includeResult.Data;
171
+
172
+                var orderByResult = OrderBy(paginationParams.OrderBy, included);
173
+                if (!orderByResult)
174
+                {
175
+                    return orderByResult.To<LuPaginatedDbo<TDbo>>();
176
+                }
177
+
178
+                var ordered = orderByResult.Data;
179
+                
180
+                var filteredResult = Filter(paginationParams.Filter, ordered);
181
+                if (!filteredResult)
182
+                {
183
+                    return filteredResult.To<LuPaginatedDbo<TDbo>>();
184
+                }
185
+
186
+                var filtered = filteredResult.Data;
187
+                var count = filtered.Count();
188
+
189
+                var paginatedResult = Paginate(paginationParams.Page, paginationParams.PerPage, filtered);
190
+                if (!paginatedResult)
191
+                {
192
+                    return paginatedResult.To<LuPaginatedDbo<TDbo>>();
193
+                }
194
+
195
+                var paginated = paginatedResult.Data;
196
+
197
+                var data = paginated.AsEnumerable().Select(model =>
198
+                    {
199
+                        var dbo = new TDbo();
200
+                        ConvertModelToDbo(partialResponse, model, dbo);
201
+                        return dbo;
202
+                    }).ToList();
203
+
204
+                return LuResult<LuPaginatedDbo<TDbo>>.Ok(new LuPaginatedDbo<TDbo>
205
+                {
206
+                    Count = count,
207
+                    Data = data
208
+                });
209
+            });
210
+            return result;
211
+        }
212
+
213
+        public virtual LuResult<IList<TDbo>> Update(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
214
+        {
215
+            throw new NotImplementedException();
216
+        }
217
+
218
+        public virtual LuResult<IList<TDbo>> Delete(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
219
+        {
220
+            throw new NotImplementedException();
221
+        }
222
+    }
223
+}

+ 186
- 0
Luticate2.Auth/Business/Fields/LuFieldsExtensions.cs Просмотреть файл

@@ -0,0 +1,186 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Linq.Expressions;
5
+using System.Text.RegularExpressions;
6
+using Luticate2.Auth.Dbo.Fields;
7
+using Luticate2.Auth.Dbo.Pagination;
8
+
9
+namespace Luticate2.Auth.Business.Fields
10
+{
11
+    public static class LuFieldsExtensions
12
+    {
13
+        public static bool IsIncluded(this IEnumerable<LuFieldDbo> fields, IEnumerable<string> parts, bool ignoreCase = true)
14
+        {
15
+            return fields.Any(x => x.IsIncluded(parts, ignoreCase));
16
+        }
17
+
18
+        public static bool IsIncluded(this IEnumerable<LuFieldDbo> fields, string path, bool ignoreCase = true)
19
+        {
20
+            return fields.Any(x => x.IsIncluded(path, ignoreCase));
21
+        }
22
+
23
+        public static bool IsIncluded(this IEnumerable<LuFieldDbo> fields, LuFieldDbo path, bool ignoreCase = true)
24
+        {
25
+            return fields.Any(x => x.IsIncluded(path, ignoreCase));
26
+        }
27
+
28
+        public static bool IsIncluded<TModel>(this IEnumerable<LuFieldDbo> fields, Expression<Func<TModel, object>> property, bool ignoreCase = true)
29
+        {
30
+            return fields.Any(x => x.IsIncluded(property, ignoreCase));
31
+        }
32
+
33
+
34
+        public static bool IsIncluded(this LuFieldDbo field, IEnumerable<string> parts, bool ignoreCase = true)
35
+        {
36
+            var list = parts.ToList();
37
+            var stringComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
38
+
39
+            for (var index = 0; index < list.Count && index < field.Parts.Count; index++)
40
+            {
41
+                if (!string.Equals(list[index], field.Parts[index], stringComparison) && field.Parts[index] != "*")
42
+                {
43
+                    return false;
44
+                }
45
+
46
+                // If the last part of the given value is reached and the field has more parts than the given value,
47
+                // there is no match, eg. the field value is foo/bar and the given value is foo. If the field parts and
48
+                // the given value parts have equal lengths, there is a match, eg. the field value is foo/bar and the
49
+                // given value is foo/bar.
50
+                if (index == list.Count - 1)
51
+                {
52
+                    return list.Count <= field.Parts.Count;
53
+                }
54
+            }
55
+
56
+            return true;
57
+        }
58
+
59
+        public static bool IsIncluded(this LuFieldDbo field, string path, bool ignoreCase = true)
60
+        {
61
+            return field.IsIncluded(LuFieldDbo.Make(path), ignoreCase);
62
+        }
63
+
64
+        public static bool IsIncluded(this LuFieldDbo field, LuFieldDbo path, bool ignoreCase = true)
65
+        {
66
+            return field.IsIncluded(path.Parts, ignoreCase);
67
+        }
68
+
69
+        public static bool IsIncluded<TModel>(this LuFieldDbo field, Expression<Func<TModel, object>> property, bool ignoreCase = true)
70
+        {
71
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression(property);
72
+            var parts = memberInfo.Select(x => x.Name).ToList();
73
+            return field.IsIncluded(parts, ignoreCase);
74
+        }
75
+
76
+
77
+        public static bool StartsWith(this LuFieldDbo field, IEnumerable<string> subParts, bool ignoreCase = true)
78
+        {
79
+            var comparer = ignoreCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture;
80
+            using (IEnumerator<string> enumerator = field.Parts.GetEnumerator())
81
+            {
82
+                foreach (string source in subParts)
83
+                {
84
+                    if (!enumerator.MoveNext() || comparer.Compare(enumerator.Current, source) != 0)
85
+                        return false;
86
+                }
87
+            }
88
+            return true;
89
+        }
90
+
91
+        public static bool StartsWith(this LuFieldDbo field, string subparts, bool ignoreCase = true)
92
+        {
93
+            return field.StartsWith(LuFieldDbo.Make(subparts), ignoreCase);
94
+        }
95
+
96
+        public static bool StartsWith(this LuFieldDbo field, LuFieldDbo path, bool ignoreCase = true)
97
+        {
98
+            return field.StartsWith(path.Parts, ignoreCase);
99
+        }
100
+
101
+        public static bool StartsWith<TDbo>(this LuFieldDbo field, Expression<Func<TDbo, object>> property, bool ignoreCase = true)
102
+        {
103
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression(property);
104
+            var memberInfoString = memberInfo.Select(x => x.Name).ToList();
105
+            return field.StartsWith(memberInfoString, ignoreCase);
106
+        }
107
+
108
+
109
+        public static bool Is(this LuFieldDbo field, IEnumerable<string> parts, bool ignoreCase = true)
110
+        {
111
+            var comparer = ignoreCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture;
112
+            return field.Parts.SequenceEqual(parts, comparer);
113
+        }
114
+
115
+        public static bool Is(this LuFieldDbo field, string parts, bool ignoreCase = true)
116
+        {
117
+            return field.Is(LuFieldDbo.Make(parts), ignoreCase);
118
+        }
119
+
120
+        public static bool Is(this LuFieldDbo field, LuFieldDbo path, bool ignoreCase = true)
121
+        {
122
+            return field.Is(path.Parts, ignoreCase);
123
+        }
124
+
125
+        public static bool Is<TDbo>(this LuFieldDbo field, Expression<Func<TDbo, object>> property, bool ignoreCase = true)
126
+        {
127
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression(property);
128
+            var memberInfoString = memberInfo.Select(x => x.Name).ToList();
129
+            return field.Is(memberInfoString, ignoreCase);
130
+        }
131
+
132
+
133
+        public static bool IsRoot(this LuFieldDbo field)
134
+        {
135
+            return !field.Parts.Any();
136
+        }
137
+
138
+        public static LuFieldDbo Pop(this LuFieldDbo field)
139
+        {
140
+            field.Parts = field.Parts.Where((s, i) => i != 0).ToList();
141
+            return field;
142
+        }
143
+
144
+        public static LuFieldDbo Popped(this LuFieldDbo field)
145
+        {
146
+            var newField = LuFieldDbo.Make(field).Pop();
147
+            return newField;
148
+        }
149
+
150
+
151
+        public static LuFieldDbo Add(this LuFieldDbo field, IEnumerable<string> parts)
152
+        {
153
+            foreach (var property in parts)
154
+            {
155
+                if (!string.IsNullOrEmpty(property))
156
+                {
157
+                    field.Parts.Add(property);
158
+                }
159
+            }
160
+
161
+            return field;
162
+        }
163
+
164
+        public static LuFieldDbo Add(this LuFieldDbo field, LuFieldDbo path)
165
+        {
166
+            return field.Add(path.Parts);
167
+        }
168
+
169
+        public static LuFieldDbo Add(this LuFieldDbo field, string path)
170
+        {
171
+            return field.Add(Regex.Split(path, "[\\./]"));
172
+        }
173
+
174
+        public static LuFieldDbo Add<TTypeTo>(this LuFieldDbo field, Expression<Func<TTypeTo, object>> property)
175
+        {
176
+            var memberInfo = LuExpressionUtils.GetMembersFromExpression(property);
177
+
178
+            if (memberInfo == null)
179
+            {
180
+                throw new ArgumentException("Invalid property", nameof(property));
181
+            }
182
+            
183
+            return field.Add(memberInfo.Select(x => x.Name));
184
+        }
185
+    }
186
+}

+ 23
- 0
Luticate2.Auth/Business/Fields/LuPartialFieldsParser.cs Просмотреть файл

@@ -0,0 +1,23 @@
1
+using System.Linq;
2
+using Luticate2.Auth.Dbo;
3
+using Luticate2.Auth.Dbo.Fields;
4
+using Luticate2.Auth.Dbo.Result;
5
+
6
+namespace Luticate2.Auth.Business.Fields
7
+{
8
+    public class LuPartialFieldsParser
9
+    {
10
+        public static LuResult<LuPartialFieldsDbo> Parse(string fields)
11
+        {
12
+            if (PartialResponse.Core.Fields.TryParse(fields, out var tempFields))
13
+            {
14
+                var partialFieldsDbo = new LuPartialFieldsDbo
15
+                {
16
+                    Fields = tempFields.Values.Select(x => new LuFieldDbo {Parts = x.Parts.ToList()}).ToList()
17
+                };
18
+                return LuResult<LuPartialFieldsDbo>.Ok(partialFieldsDbo);
19
+            }
20
+            return LuResult<LuPartialFieldsDbo>.Error(LuStatus.InputError.ToInt(), "Failed to parse partial fields", "");
21
+        }
22
+    }
23
+}

+ 24
- 0
Luticate2.Auth/Business/FieldsExpressions/Basic/LuFieldsExpressionsString.cs Просмотреть файл

@@ -0,0 +1,24 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Business.Fields;
4
+using Luticate2.Auth.Dbo.Fields;
5
+using Luticate2.Auth.Dbo.Result;
6
+
7
+namespace Luticate2.Auth.Business.FieldsExpressions.Basic
8
+{
9
+    public class LuFieldsExpressionsString : LuFieldsExpressions<string, string>
10
+    {
11
+        public LuFieldsExpressionsString(IServiceProvider serviceProvider) : base(serviceProvider)
12
+        {
13
+        }
14
+
15
+        protected override LuResult<Expression<Func<TType1, object>>> GetExpressionInternal<TType1>(Expression<Func<TType1, string>> modelProperty, LuFieldDbo field)
16
+        {
17
+            if (field.StartsWith<string>(x => x.Length))
18
+            {
19
+                return GetSubField<TType1, int, int>(modelProperty, field, x => x.Length);
20
+            }
21
+            return base.GetExpressionInternal(modelProperty, field);
22
+        }
23
+    }
24
+}

+ 60
- 0
Luticate2.Auth/Business/FieldsExpressions/LuFieldsExpressions.cs Просмотреть файл

@@ -0,0 +1,60 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Business.Fields;
4
+using Luticate2.Auth.Dbo;
5
+using Luticate2.Auth.Dbo.Fields;
6
+using Luticate2.Auth.Dbo.Result;
7
+using Luticate2.Auth.Interfaces;
8
+using Microsoft.Extensions.DependencyInjection;
9
+
10
+namespace Luticate2.Auth.Business.FieldsExpressions
11
+{
12
+    public class LuFieldsExpressions<TDbo, TModel> : ILuFieldsExpressions<TDbo, TModel>
13
+    {
14
+        protected IServiceProvider ServiceProvider { get; }
15
+
16
+        public LuFieldsExpressions(IServiceProvider serviceProvider)
17
+        {
18
+            ServiceProvider = serviceProvider;
19
+        }
20
+        
21
+        public ILuFieldsExpressions<TDbo2, TModel2> GetService<TDbo2, TModel2>()
22
+        {
23
+            var service = ServiceProvider.GetService<ILuFieldsExpressions<TDbo2, TModel2>>();
24
+            return service;
25
+        }
26
+
27
+        protected LuResult<Expression<Func<TType1, object>>> GetSubField<TType1, TType2, TType3>(
28
+            Expression<Func<TType1, TModel>> modelProperty, LuFieldDbo field, Expression<Func<TModel, TType3>> modelSubProperty)
29
+        {
30
+            var subPropExprResult = LuExpressionUtils.GetSingleMemberFromExpression(modelSubProperty);
31
+            if (subPropExprResult == null)
32
+            {
33
+                return LuResult<Expression<Func<TType1, object>>>.Error(LuStatus.InternalError.ToInt(), "Bad field expression");
34
+            }
35
+
36
+            var prop = Expression.Property(modelProperty.Body, subPropExprResult.Name);
37
+            var exp = Expression.Lambda<Func<TType1, TType3>>(prop, modelProperty.Parameters[0]);
38
+            var service = GetService<TType2, TType3>();
39
+            var finalExpResult = service.GetExpression(exp, field.Popped());
40
+            return finalExpResult;
41
+        }
42
+
43
+        protected virtual LuResult<Expression<Func<TType1, object>>> GetExpressionInternal<TType1>(
44
+            Expression<Func<TType1, TModel>> modelProperty, LuFieldDbo field)
45
+        {
46
+            return LuResult<Expression<Func<TType1, object>>>.Error(LuStatus.InputError.ToInt(), $"Unknown field: {field}", "");
47
+        }
48
+
49
+        public virtual LuResult<Expression<Func<TType1, object>>> GetExpression<TType1>(Expression<Func<TType1, TModel>> modelProperty, LuFieldDbo field)
50
+        {
51
+            if (field.IsRoot())
52
+            {
53
+                var converted = Expression.Convert(modelProperty.Body, typeof(object));
54
+                var exp = Expression.Lambda<Func<TType1, object>>(converted, modelProperty.Parameters[0]);
55
+                return LuResult<Expression<Func<TType1, object>>>.Ok(exp);
56
+            }
57
+            return GetExpressionInternal(modelProperty, field);
58
+        }
59
+    }
60
+}

+ 143
- 0
Luticate2.Auth/Business/LuExpressionUtils.cs Просмотреть файл

@@ -0,0 +1,143 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Linq.Expressions;
5
+using System.Reflection;
6
+using Luticate2.Auth.Dbo;
7
+using Luticate2.Auth.Dbo.Result;
8
+
9
+namespace Luticate2.Auth.Business
10
+{
11
+    public static class LuExpressionUtils
12
+    {
13
+        public static Expression GetFromConvert<TType1, TType2>(Expression<Func<TType1, TType2>> exp)
14
+        {
15
+            Expression operand;
16
+            if ((exp.Body.NodeType == ExpressionType.Convert ||
17
+                 exp.Body.NodeType == ExpressionType.ConvertChecked)
18
+                && exp.Body is UnaryExpression)
19
+            {
20
+                operand = ((UnaryExpression) exp.Body).Operand;
21
+            }
22
+            else
23
+            {
24
+                operand = exp.Body;
25
+            }
26
+
27
+            return operand;
28
+        }
29
+
30
+        public static Expression<Func<TType1, TType3>> AddConvert<TType1, TType2, TType3>(Expression<Func<TType1, TType2>> exp)
31
+        {
32
+            var converted = Expression.Convert(exp, typeof(object));
33
+            var expLambda = Expression.Lambda<Func<TType1, TType3>>(converted, exp.Parameters);
34
+            return expLambda;
35
+        }
36
+
37
+        public static LuResult<TProperty> SetValueFromExpression<TDbo, TProperty>(Expression<Func<TDbo, TProperty>> property,
38
+            TDbo dboTo, TProperty value)
39
+        {
40
+            var memberInfo = GetSingleMemberFromExpression(property);
41
+            if (memberInfo != null)
42
+            {
43
+                switch (memberInfo.MemberType)
44
+                {
45
+                    case MemberTypes.Field:
46
+                        ((FieldInfo) memberInfo).SetValue(dboTo, value);
47
+                        return LuResult<TProperty>.Ok(value);
48
+                    case MemberTypes.Property:
49
+                        ((PropertyInfo) memberInfo).SetValue(dboTo, value);
50
+                        return LuResult<TProperty>.Ok(value);
51
+                    default:
52
+                        return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(),
53
+                            $"Bad MemberType: {memberInfo.MemberType}");
54
+                }
55
+            }
56
+
57
+            return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(), "Bad member expression");
58
+        }
59
+
60
+        public static LuResult<TProperty> GetValueFromExpression<TDbo, TProperty>(Expression<Func<TDbo, TProperty>> property,
61
+            TDbo dboTo)
62
+        {
63
+            var memberInfo = GetSingleMemberFromExpression(property);
64
+            if (memberInfo != null)
65
+            {
66
+                TProperty value;
67
+                switch (memberInfo.MemberType)
68
+                {
69
+                    case MemberTypes.Field:
70
+                        value = (TProperty) ((FieldInfo) memberInfo).GetValue(dboTo);
71
+                        return LuResult<TProperty>.Ok(value);
72
+                    case MemberTypes.Property:
73
+                        value = (TProperty) ((PropertyInfo) memberInfo).GetValue(dboTo);
74
+                        return LuResult<TProperty>.Ok(value);
75
+                    default:
76
+                        return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(),
77
+                            $"Bad MemberType: {memberInfo.MemberType}");
78
+                }
79
+            }
80
+
81
+            return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(), "Bad member expression");
82
+        }
83
+
84
+        public static MemberInfo GetSingleMemberFromExpression<TTypeTo, TProperty>(Expression<Func<TTypeTo, TProperty>> property)
85
+        {
86
+            var memberExpression = GetFromConvert(property) as MemberExpression;
87
+
88
+            if (memberExpression != null && memberExpression.Expression == property.Parameters.First())
89
+            {
90
+                return memberExpression.Member;
91
+            }
92
+            return null;
93
+        }
94
+
95
+        private static bool GetMembersFromExpression<TTypeTo, TProperty>(
96
+            Expression<Func<TTypeTo, TProperty>> property, IList<MemberInfo> memberInfos)
97
+        {
98
+            MemberExpression memberExpression;
99
+            if ((property.Body.NodeType == ExpressionType.Convert ||
100
+                 property.Body.NodeType == ExpressionType.ConvertChecked)
101
+                && property.Body is UnaryExpression)
102
+            {
103
+                memberExpression = ((UnaryExpression) property.Body).Operand as MemberExpression;
104
+            }
105
+            else
106
+            {
107
+                memberExpression = property.Body as MemberExpression;
108
+            }
109
+
110
+            if (memberExpression != null)
111
+            {
112
+                if (memberExpression.Expression == property.Parameters.First())
113
+                {
114
+                    memberInfos.Add(memberExpression.Member);
115
+                    return true;
116
+                }
117
+                else if (memberExpression.Expression is MemberExpression)
118
+                {
119
+                    var exp = Expression.Lambda<Func<TTypeTo, object>>(memberExpression.Expression, property.Parameters);
120
+                    var res = GetMembersFromExpression(exp, memberInfos);
121
+                    if (res)
122
+                    {
123
+                        memberInfos.Add(memberExpression.Member);
124
+                    }
125
+
126
+                    return res;
127
+                }
128
+            }
129
+            return false;
130
+        }
131
+
132
+        public static IList<MemberInfo> GetMembersFromExpression<TTypeTo, TProperty>(Expression<Func<TTypeTo, TProperty>> property)
133
+        {
134
+            var list = new List<MemberInfo>();
135
+            if (GetMembersFromExpression(property, list))
136
+            {
137
+                return list;
138
+            }
139
+
140
+            return null;
141
+        }
142
+    }
143
+}

+ 31
- 0
Luticate2.Auth/Business/Pagination/LuFilterParser.cs Просмотреть файл

@@ -0,0 +1,31 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Dbo;
4
+using Luticate2.Auth.Dbo.Pagination;
5
+using Luticate2.Auth.Dbo.Result;
6
+using Microsoft.CodeAnalysis.CSharp.Scripting;
7
+using Microsoft.CodeAnalysis.Scripting;
8
+
9
+namespace Luticate2.Auth.Business.Pagination
10
+{
11
+    public class LuFilterParser
12
+    {
13
+        public static LuResult<LuFilterDbo> Parse<T>(string data)
14
+        {
15
+            var completeData = $"(x) => ({data})";
16
+            try
17
+            {
18
+                var options = ScriptOptions.Default.AddReferences(typeof(LuFilterParser).Assembly);
19
+                var expr = CSharpScript.EvaluateAsync<Expression<Func<T, bool>>>(completeData, options).Result;
20
+                return LuResult<LuFilterDbo>.Ok(new LuFilterDbo
21
+                {
22
+                    Expression = expr
23
+                });
24
+            }
25
+            catch (Exception e)
26
+            {
27
+                return LuResult<LuFilterDbo>.Error(LuStatus.InputError.ToInt(), e);
28
+            }
29
+        }
30
+    }
31
+}

+ 58
- 0
Luticate2.Auth/Business/Pagination/LuOrderByParser.cs Просмотреть файл

@@ -0,0 +1,58 @@
1
+using System.Collections.Generic;
2
+using Luticate2.Auth.Dbo;
3
+using Luticate2.Auth.Dbo.Fields;
4
+using Luticate2.Auth.Dbo.Pagination;
5
+using Luticate2.Auth.Dbo.Result;
6
+
7
+namespace Luticate2.Auth.Business.Pagination
8
+{
9
+    public class LuOrderByParser
10
+    {
11
+        public static LuResult<LuOrderByDbo> Parse(string data)
12
+        {
13
+            if (data == null)
14
+            {
15
+                data = "";
16
+            }
17
+            data = data.Trim();
18
+            if (data != "")
19
+            {
20
+                var dbo = new LuOrderByDbo {OrderByFields = new List<LuOrderByFieldDbo>()};
21
+                var fields = data.Split(',');
22
+                foreach (var field in fields)
23
+                {
24
+                    if (field == "")
25
+                    {
26
+                        return LuResult<LuOrderByDbo>.Error(LuStatus.InputError.ToInt(),
27
+                            $"LuOrderByParser: {data}", "Empty order by field");
28
+                    }
29
+                    var orderByField = new LuOrderByFieldDbo();
30
+                    var split = field.Split(':');
31
+                    if (split.Length > 2 || split.Length == 0)
32
+                    {
33
+                        return LuResult<LuOrderByDbo>.Error(LuStatus.InputError.ToInt(),
34
+                            $"LuOrderByParser: {data}", "Invalid order by field syntax");
35
+                    }
36
+                    orderByField.Field = LuFieldDbo.Make(split[0]);
37
+                    var order = split.Length == 2 ? split[1].ToLower() : "asc";
38
+                    if (order == "asc")
39
+                    {
40
+                        orderByField.Asc = true;
41
+                    }
42
+                    else if (order == "desc")
43
+                    {
44
+                        orderByField.Asc = false;
45
+                    }
46
+                    else
47
+                    {
48
+                        return LuResult<LuOrderByDbo>.Error(LuStatus.InputError.ToInt(),
49
+                            $"LuOrderByParser: {data}", "Empty order by field order");
50
+                    }
51
+                    dbo.OrderByFields.Add(orderByField);
52
+                }
53
+                return LuResult<LuOrderByDbo>.Ok(dbo);
54
+            }
55
+            return LuResult<LuOrderByDbo>.Error(LuStatus.InputError.ToInt(), "Order by is empty or missing", "");
56
+        }
57
+    }
58
+}

+ 114
- 0
Luticate2.Auth/Business/PartialObjectCopier/LuPartialObjectCopier.cs Просмотреть файл

@@ -0,0 +1,114 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq.Expressions;
4
+using Luticate2.Auth.Business.Fields;
5
+using Luticate2.Auth.Dbo;
6
+using Luticate2.Auth.Dbo.Fields;
7
+using Luticate2.Auth.Dbo.PartialObjectCopier;
8
+using Luticate2.Auth.Dbo.Result;
9
+using Luticate2.Auth.Interfaces;
10
+using Microsoft.Extensions.DependencyInjection;
11
+
12
+namespace Luticate2.Auth.Business.PartialObjectCopier
13
+{
14
+    public abstract class LuPartialObjectCopier<TTypeFrom, TTypeTo> : ILuPartialObjectCopier<TTypeFrom, TTypeTo>
15
+    {
16
+        protected IServiceProvider ServiceProvider { get; }
17
+
18
+        protected LuPartialObjectCopier(IServiceProvider serviceProvider)
19
+        {
20
+            ServiceProvider = serviceProvider;
21
+        }
22
+
23
+        protected LuResult<TPropertyTo> MayCopySubProperty<TPropertyFrom, TPropertyTo>(LuFieldDbo path,
24
+            LuPartialFieldsDbo fields, TTypeFrom modelFrom, TTypeTo dboTo,
25
+            Expression<Func<TTypeFrom, TPropertyFrom>> propFrom, Expression<Func<TTypeTo, TPropertyTo>> propTo,
26
+            LuPartialObjectCopierOptions options) where TPropertyTo : new()
27
+        {
28
+            var member = LuExpressionUtils.GetSingleMemberFromExpression(propTo);
29
+            var subpath = LuFieldDbo.Make(path).Add(member.Name);
30
+            if (fields.Fields.IsIncluded(subpath))
31
+            {
32
+                var propToValue = LuExpressionUtils.GetValueFromExpression(propTo, dboTo);
33
+                if (!propToValue)
34
+                {
35
+                    return propToValue.To<TPropertyTo>();
36
+                }
37
+                if (propToValue.Data == null)
38
+                {
39
+                    propToValue.Data = new TPropertyTo();
40
+                    var res = LuExpressionUtils.SetValueFromExpression(propTo, dboTo, propToValue.Data);
41
+                    if (!res)
42
+                    {
43
+                        return res.To<TPropertyTo>();
44
+                    }
45
+                }
46
+                var propFromValue = LuExpressionUtils.GetValueFromExpression(propFrom, modelFrom);
47
+                if (!propFromValue)
48
+                {
49
+                    return propFromValue.To<TPropertyTo>();
50
+                }
51
+
52
+                var service = ServiceProvider.GetService<ILuPartialObjectCopier<TPropertyFrom, TPropertyTo>>();
53
+                var result = service.Copy(subpath, fields, propFromValue.Data, propToValue.Data, options);
54
+                return result;
55
+            }
56
+            return LuResult<TPropertyTo>.Ok(default(TPropertyTo));
57
+        }
58
+
59
+        protected LuResult<IList<TPropertyTo>> MayCopySubPropertyList<TPropertyFrom, TPropertyTo>(
60
+            LuFieldDbo path, LuPartialFieldsDbo fields, IEnumerable<TPropertyFrom> modelFrom,
61
+            TTypeTo dboTo, Expression<Func<TTypeTo, IEnumerable<TPropertyTo>>> propTo,
62
+            LuPartialObjectCopierOptions options) where TPropertyTo : new()
63
+        {
64
+            var member = LuExpressionUtils.GetSingleMemberFromExpression(propTo);
65
+            var subpath = LuFieldDbo.Make(path).Add(member.Name);
66
+            if (fields.Fields.IsIncluded(subpath))
67
+            {
68
+                var list = new List<TPropertyTo>();
69
+                var res = LuExpressionUtils.SetValueFromExpression(propTo, dboTo, list);
70
+                if (!res)
71
+                {
72
+                    return res.To<IList<TPropertyTo>>();
73
+                }
74
+
75
+                foreach (var subDboFrom in modelFrom)
76
+                {
77
+                    var subDboTo = new TPropertyTo();
78
+
79
+                    var service = ServiceProvider.GetService<ILuPartialObjectCopier<TPropertyFrom, TPropertyTo>>();
80
+                    var result = service.Copy(subpath, fields, subDboFrom, subDboTo, options);
81
+
82
+                    list.Add(subDboTo);
83
+                }
84
+            }
85
+            return LuResult<IList<TPropertyTo>>.Ok(null);
86
+        }
87
+
88
+        protected LuResult<TProperty> MayCopy<TProperty, TTypeTo2>(LuFieldDbo path, LuPartialFieldsDbo fields,
89
+            TTypeTo2 dboTo, Expression<Func<TTypeTo2, TProperty>> property, Func<TProperty> getValue)
90
+        {
91
+            var memberInfo = LuExpressionUtils.GetSingleMemberFromExpression(property);
92
+            if (memberInfo != null)
93
+            {
94
+                if (fields.Fields.IsIncluded(LuFieldDbo.Make(path).Add(memberInfo.Name)))
95
+                {
96
+                    var value = getValue();
97
+                    var result = LuExpressionUtils.SetValueFromExpression(property, dboTo, value);
98
+                    return result;
99
+                }
100
+
101
+                return LuResult<TProperty>.Ok(default(TProperty));
102
+            }
103
+
104
+            return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(), "Bad member expression");
105
+        }
106
+
107
+        public abstract LuResult<TTypeTo> Copy(LuFieldDbo path, LuPartialFieldsDbo fields, TTypeFrom dboFrom, TTypeTo dboTo, LuPartialObjectCopierOptions options);
108
+
109
+        public LuResult<TTypeTo> Copy(LuPartialFieldsDbo fields, TTypeFrom dboFrom, TTypeTo dboTo, LuPartialObjectCopierOptions options)
110
+        {
111
+            return Copy(new LuFieldDbo(), fields, dboFrom, dboTo, options);
112
+        }
113
+    }
114
+}

+ 11
- 0
Luticate2.Auth/Business/PartialObjectCopier/LuPartialObjectCopierExtensions.cs Просмотреть файл

@@ -0,0 +1,11 @@
1
+namespace Luticate2.Auth.Business.PartialObjectCopier
2
+{
3
+    public static class LuPartialObjectCopierExtensions
4
+    {
5
+//        public static LuResult<TTypeTo> CopyList<TTypeFrom, TTypeTo>(this ILuPartialObjectCopier<TTypeFrom, TTypeTo> copier,
6
+//            ILuPartialFields fields, TTypeFrom dboFrom, TTypeTo dboTo)
7
+//        {
8
+//
9
+//        }
10
+    }
11
+}

+ 147
- 0
Luticate2.Auth/Business/Serializers/PartialJson/LuJsonSerializerExtensions.cs Просмотреть файл

@@ -0,0 +1,147 @@
1
+using System;
2
+using System.Linq;
3
+using Newtonsoft.Json;
4
+using Newtonsoft.Json.Linq;
5
+
6
+namespace Luticate2.Auth.Business.Serializers.PartialJson
7
+{
8
+    /// <summary>
9
+    /// Provides a method for serializing objects to JSON.
10
+    /// </summary>
11
+    /// <remarks>This type supports the <see cref="PartialResponse.Core.Fields"/> infrastructure and is not intended to be used directly
12
+    /// from your code.</remarks>
13
+    public static class LuJsonSerializerExtensions
14
+    {
15
+        /// <summary>
16
+        /// Serializes the specified <see cref="object"/> and writes the JSON structure
17
+        /// using the specified <see cref="JsonWriter"/>.
18
+        /// </summary>
19
+        /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> used to serialize the specified <see cref="object"/>.</param>
20
+        /// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the JSON structure.</param>
21
+        /// <param name="value">The <see cref="object"/> to serialize.</param>
22
+        /// <param name="shouldSerialize">A <see cref="Func{T, TResult}"/> that is called for every field in the
23
+        /// <see cref="object"/> to serialize, indicating whether the field should be serialized.</param>
24
+        public static void Serialize(this JsonSerializer jsonSerializer, JsonWriter jsonWriter, object value, Func<string, bool> shouldSerialize)
25
+        {
26
+            if (value == null)
27
+            {
28
+                jsonSerializer.Serialize(jsonWriter, value);
29
+            }
30
+            else
31
+            {
32
+                var context = new LuSerializerContext(shouldSerialize);
33
+                var token = JToken.FromObject(value, jsonSerializer);
34
+
35
+                if (token is JArray array)
36
+                {
37
+                    RemoveArrayElements(array, null, context);
38
+
39
+                    array.WriteTo(jsonWriter);
40
+                }
41
+                else
42
+                {
43
+                    if (token is JObject @object)
44
+                    {
45
+                        RemoveObjectProperties(@object, null, context);
46
+
47
+                        @object.WriteTo(jsonWriter);
48
+                    }
49
+                    else
50
+                    {
51
+                        token.WriteTo(jsonWriter);
52
+                    }
53
+                }
54
+            }
55
+        }
56
+
57
+        private static void RemoveArrayElements(JArray array, string currentPath, LuSerializerContext context)
58
+        {
59
+            var containsChildItems = array.Count > 0;
60
+
61
+            array.OfType<JObject>()
62
+                .ToList()
63
+                .ForEach(childObject => RemoveObjectProperties(childObject, currentPath, context));
64
+
65
+            // PartialResponse should only remove an array when it initially contained items, but was empty after filtering.
66
+            if (containsChildItems)
67
+            {
68
+                RemoveArrayIfEmpty(array);
69
+            }
70
+        }
71
+
72
+        private static void RemoveArrayIfEmpty(JArray array)
73
+        {
74
+            if (array.Count == 0)
75
+            {
76
+                if (array.Parent is JProperty && array.Parent.Parent != null)
77
+                {
78
+                    array.Parent.Remove();
79
+                }
80
+                else if (array.Parent is JArray)
81
+                {
82
+                    array.Remove();
83
+                }
84
+            }
85
+        }
86
+
87
+        private static void RemoveObjectProperties(JObject @object, string currentPath, LuSerializerContext context)
88
+        {
89
+            @object.Properties()
90
+                .Where(property =>
91
+                {
92
+                    var path = CombinePath(currentPath, property.Name);
93
+
94
+                    return !context.ShouldSerialize(path);
95
+                })
96
+                .ToList()
97
+                .ForEach(property => property.Remove());
98
+
99
+            @object.Properties()
100
+                .Where(property => property.Value is JObject)
101
+                .ToList()
102
+                .ForEach(property =>
103
+                {
104
+                    var path = CombinePath(currentPath, property.Name);
105
+
106
+                    RemoveObjectProperties((JObject)property.Value, path, context);
107
+                });
108
+
109
+            @object.Properties()
110
+                .Where(property => property.Value is JArray)
111
+                .ToList()
112
+                .ForEach(property =>
113
+                {
114
+                    var path = CombinePath(currentPath, property.Name);
115
+
116
+                    RemoveArrayElements((JArray)property.Value, path, context);
117
+                });
118
+
119
+            RemoveObjectIfEmpty(@object);
120
+        }
121
+
122
+        private static void RemoveObjectIfEmpty(JObject @object)
123
+        {
124
+            if (!@object.Properties().Any())
125
+            {
126
+                if (@object.Parent is JProperty && @object.Parent.Parent != null)
127
+                {
128
+                    @object.Parent.Remove();
129
+                }
130
+                else if (@object.Parent is JArray)
131
+                {
132
+                    @object.Remove();
133
+                }
134
+            }
135
+        }
136
+
137
+        private static string CombinePath(string path, string name)
138
+        {
139
+            if (string.IsNullOrEmpty(path))
140
+            {
141
+                return name;
142
+            }
143
+
144
+            return $"{path}/{name}";
145
+        }
146
+    }
147
+}

+ 30
- 0
Luticate2.Auth/Business/Serializers/PartialJson/LuPartialJsonWriter.cs Просмотреть файл

@@ -0,0 +1,30 @@
1
+using System.IO;
2
+using Luticate2.Auth.Business.Fields;
3
+using Luticate2.Auth.Dbo.Fields;
4
+using Newtonsoft.Json;
5
+
6
+namespace Luticate2.Auth.Business.Serializers.PartialJson
7
+{
8
+    public class LuPartialJsonWriter
9
+    {
10
+        public static string SerializeObject(object data, LuPartialFieldsDbo partialResponseDbo, JsonSerializerSettings settings)
11
+        {
12
+            var stringWriter = new StringWriter();
13
+            SerializeObject(data, partialResponseDbo, settings, stringWriter);
14
+            var result = stringWriter.ToString();
15
+            return result;
16
+        }
17
+
18
+        public static void SerializeObject(object data, LuPartialFieldsDbo partialResponseDbo, JsonSerializerSettings settings, TextWriter writer)
19
+        {
20
+            using (var jsonWriter = new JsonTextWriter(writer))
21
+            {
22
+                jsonWriter.CloseOutput = false;
23
+
24
+                var jsonSerializer = JsonSerializer.Create(settings);
25
+
26
+                jsonSerializer.Serialize(jsonWriter, data, path => partialResponseDbo.Fields.IsIncluded(path));
27
+            }
28
+        }
29
+    }
30
+}

+ 30
- 0
Luticate2.Auth/Business/Serializers/PartialJson/LuSerializerContext.cs Просмотреть файл

@@ -0,0 +1,30 @@
1
+using System;
2
+using System.Collections.Generic;
3
+
4
+namespace Luticate2.Auth.Business.Serializers.PartialJson
5
+{
6
+    internal class LuSerializerContext
7
+    {
8
+        private readonly Func<string, bool> shouldSerialize;
9
+        private readonly Dictionary<string, bool> cache = new Dictionary<string, bool>();
10
+
11
+        public LuSerializerContext(Func<string, bool> shouldSerialize)
12
+        {
13
+            this.shouldSerialize = shouldSerialize;
14
+        }
15
+
16
+        public bool ShouldSerialize(string path)
17
+        {
18
+            if (this.cache.ContainsKey(path))
19
+            {
20
+                return this.cache[path];
21
+            }
22
+
23
+            var result = this.shouldSerialize(path);
24
+
25
+            this.cache.Add(path, result);
26
+
27
+            return result;
28
+        }
29
+    }
30
+}

+ 0
- 12
Luticate2.Auth/Class1.cs Просмотреть файл

@@ -1,12 +0,0 @@
1
-using System;
2
-
3
-namespace Luticate2.Auth
4
-{
5
-    public class Class1
6
-    {
7
-        public static string Method1(string arg1)
8
-        {
9
-            return $"testValue {arg1}";
10
-        }
11
-    }
12
-}

+ 122
- 0
Luticate2.Auth/DataAccess/Luticate2DbContext.cs Просмотреть файл

@@ -0,0 +1,122 @@
1
+using Luticate2.Auth.DataAccess.Models;
2
+using Microsoft.EntityFrameworkCore;
3
+
4
+namespace Luticate2.Auth.DataAccess
5
+{
6
+    public class Luticate2DbContext : DbContext
7
+    {
8
+        public virtual DbSet<LuGroups> LuGroups { get; set; }
9
+        public virtual DbSet<LuGroupsObjects> LuGroupsObjects { get; set; }
10
+        public virtual DbSet<LuObjectsMetadata> LuObjectsMetadata { get; set; }
11
+        public virtual DbSet<LuUsers> LuUsers { get; set; }
12
+
13
+        public Luticate2DbContext()
14
+        {
15
+        }
16
+
17
+        public Luticate2DbContext(DbContextOptions options) : base(options)
18
+        {
19
+        }
20
+        
21
+        protected override void OnModelCreating(ModelBuilder modelBuilder)
22
+        {
23
+            modelBuilder.HasPostgresExtension("citext")
24
+                .HasPostgresExtension("unaccent")
25
+                .HasPostgresExtension("uuid-ossp");
26
+
27
+            modelBuilder.Entity<LuGroups>(entity =>
28
+            {
29
+                entity.ToTable("lu_groups", "luticate2");
30
+
31
+                entity.HasIndex(e => e.Name)
32
+                    .HasName("lu_groups_name_key")
33
+                    .IsUnique();
34
+
35
+                entity.Property(e => e.Id)
36
+                    .HasColumnName("id")
37
+                    .HasDefaultValueSql("luticate2.lu_sp_generate_uuid('lu_groups'::text)");
38
+
39
+                entity.Property(e => e.Name)
40
+                    .IsRequired()
41
+                    .HasColumnName("name")
42
+                    .HasColumnType("citext");
43
+
44
+                entity.HasOne(d => d.IdNavigation)
45
+                    .WithOne(p => p.LuGroups)
46
+                    .HasForeignKey<LuGroups>(d => d.Id)
47
+                    .OnDelete(DeleteBehavior.ClientSetNull)
48
+                    .HasConstraintName("lu_groups_id_fkey");
49
+            });
50
+
51
+            modelBuilder.Entity<LuGroupsObjects>(entity =>
52
+            {
53
+                entity.HasKey(e => new { e.GroupId, e.ObjectId });
54
+
55
+                entity.ToTable("lu_groups_objects", "luticate2");
56
+
57
+                entity.HasIndex(e => new { e.ObjectId, e.Priority })
58
+                    .HasName("lu_groups_objects_object_id_priority_key")
59
+                    .IsUnique();
60
+
61
+                entity.Property(e => e.GroupId).HasColumnName("group_id");
62
+
63
+                entity.Property(e => e.ObjectId).HasColumnName("object_id");
64
+
65
+                entity.Property(e => e.Priority).HasColumnName("priority");
66
+
67
+                entity.HasOne(d => d.Group)
68
+                    .WithMany(p => p.LuGroupsObjects)
69
+                    .HasForeignKey(d => d.GroupId)
70
+                    .HasConstraintName("lu_groups_objects_group_id_fkey");
71
+
72
+                entity.HasOne(d => d.Object)
73
+                    .WithMany(p => p.LuGroupsObjects)
74
+                    .HasForeignKey(d => d.ObjectId)
75
+                    .OnDelete(DeleteBehavior.ClientSetNull)
76
+                    .HasConstraintName("lu_groups_objects_object_id_fkey");
77
+            });
78
+
79
+            modelBuilder.Entity<LuObjectsMetadata>(entity =>
80
+            {
81
+                entity.ToTable("lu_objects_metadata", "luticate2");
82
+
83
+                entity.Property(e => e.Id)
84
+                    .HasColumnName("id")
85
+                    .HasDefaultValueSql("luticate2.lu_sp_generate_uuid('lu_objects_metadata'::text)");
86
+
87
+                entity.Property(e => e.CreatedAt)
88
+                    .HasColumnName("created_at")
89
+                    .HasColumnType("timestamp with time zone")
90
+                    .HasDefaultValueSql("now()");
91
+
92
+                entity.Property(e => e.UpdatedAt)
93
+                    .HasColumnName("updated_at")
94
+                    .HasColumnType("timestamp with time zone");
95
+            });
96
+
97
+            modelBuilder.Entity<LuUsers>(entity =>
98
+            {
99
+                entity.ToTable("lu_users", "luticate2");
100
+
101
+                entity.HasIndex(e => e.Username)
102
+                    .HasName("lu_users_username_key")
103
+                    .IsUnique();
104
+
105
+                entity.Property(e => e.Id)
106
+                    .HasColumnName("id")
107
+                    .HasDefaultValueSql("luticate2.lu_sp_generate_uuid('lu_users'::text)");
108
+
109
+                entity.Property(e => e.Username)
110
+                    .IsRequired()
111
+                    .HasColumnName("username")
112
+                    .HasColumnType("citext");
113
+
114
+                entity.HasOne(d => d.IdNavigation)
115
+                    .WithOne(p => p.LuUsers)
116
+                    .HasForeignKey<LuUsers>(d => d.Id)
117
+                    .OnDelete(DeleteBehavior.ClientSetNull)
118
+                    .HasConstraintName("lu_users_id_fkey");
119
+            });
120
+        }
121
+    }
122
+}

+ 19
- 0
Luticate2.Auth/DataAccess/Models/LuGroups.cs Просмотреть файл

@@ -0,0 +1,19 @@
1
+using System;
2
+using System.Collections.Generic;
3
+
4
+namespace Luticate2.Auth.DataAccess.Models
5
+{
6
+    public partial class LuGroups
7
+    {
8
+        public LuGroups()
9
+        {
10
+            LuGroupsObjects = new HashSet<LuGroupsObjects>();
11
+        }
12
+
13
+        public Guid Id { get; set; }
14
+        public string Name { get; set; }
15
+
16
+        public LuObjectsMetadata IdNavigation { get; set; }
17
+        public ICollection<LuGroupsObjects> LuGroupsObjects { get; set; }
18
+    }
19
+}

+ 15
- 0
Luticate2.Auth/DataAccess/Models/LuGroupsObjects.cs Просмотреть файл

@@ -0,0 +1,15 @@
1
+using System;
2
+using System.Collections.Generic;
3
+
4
+namespace Luticate2.Auth.DataAccess.Models
5
+{
6
+    public partial class LuGroupsObjects
7
+    {
8
+        public Guid GroupId { get; set; }
9
+        public Guid ObjectId { get; set; }
10
+        public int? Priority { get; set; }
11
+
12
+        public LuGroups Group { get; set; }
13
+        public LuObjectsMetadata Object { get; set; }
14
+    }
15
+}

+ 21
- 0
Luticate2.Auth/DataAccess/Models/LuObjectsMetadata.cs Просмотреть файл

@@ -0,0 +1,21 @@
1
+using System;
2
+using System.Collections.Generic;
3
+
4
+namespace Luticate2.Auth.DataAccess.Models
5
+{
6
+    public partial class LuObjectsMetadata
7
+    {
8
+        public LuObjectsMetadata()
9
+        {
10
+            LuGroupsObjects = new HashSet<LuGroupsObjects>();
11
+        }
12
+
13
+        public Guid Id { get; set; }
14
+        public DateTime CreatedAt { get; set; }
15
+        public DateTime? UpdatedAt { get; set; }
16
+
17
+        public LuGroups LuGroups { get; set; }
18
+        public LuUsers LuUsers { get; set; }
19
+        public ICollection<LuGroupsObjects> LuGroupsObjects { get; set; }
20
+    }
21
+}

+ 13
- 0
Luticate2.Auth/DataAccess/Models/LuUsers.cs Просмотреть файл

@@ -0,0 +1,13 @@
1
+using System;
2
+using System.Collections.Generic;
3
+
4
+namespace Luticate2.Auth.DataAccess.Models
5
+{
6
+    public partial class LuUsers
7
+    {
8
+        public Guid Id { get; set; }
9
+        public string Username { get; set; }
10
+
11
+        public LuObjectsMetadata IdNavigation { get; set; }
12
+    }
13
+}

+ 10
- 0
Luticate2.Auth/DataAccess/Models/TestTable.cs Просмотреть файл

@@ -0,0 +1,10 @@
1
+using System;
2
+using System.Collections.Generic;
3
+
4
+namespace Luticate2.Auth.DataAccess.Models
5
+{
6
+    public partial class TestTable
7
+    {
8
+        public Guid Id { get; set; }
9
+    }
10
+}

+ 133
- 0
Luticate2.Auth/DataAccess/Models/luticate2Context.cs Просмотреть файл

@@ -0,0 +1,133 @@
1
+using System;
2
+using Microsoft.EntityFrameworkCore;
3
+using Microsoft.EntityFrameworkCore.Metadata;
4
+
5
+namespace Luticate2.Auth.DataAccess.Models
6
+{
7
+    public partial class luticate2Context : DbContext
8
+    {
9
+        public luticate2Context()
10
+        {
11
+        }
12
+
13
+        public luticate2Context(DbContextOptions<luticate2Context> options)
14
+            : base(options)
15
+        {
16
+        }
17
+
18
+        public virtual DbSet<LuGroups> LuGroups { get; set; }
19
+        public virtual DbSet<LuGroupsObjects> LuGroupsObjects { get; set; }
20
+        public virtual DbSet<LuObjectsMetadata> LuObjectsMetadata { get; set; }
21
+        public virtual DbSet<LuUsers> LuUsers { get; set; }
22
+
23
+        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
24
+        {
25
+            if (!optionsBuilder.IsConfigured)
26
+            {
27
+#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
28
+                optionsBuilder.UseNpgsql("Host=localhost;Database=luticate2;Username=dev;Password=dev");
29
+            }
30
+        }
31
+
32
+        protected override void OnModelCreating(ModelBuilder modelBuilder)
33
+        {
34
+            modelBuilder.HasPostgresExtension("citext")
35
+                .HasPostgresExtension("unaccent")
36
+                .HasPostgresExtension("uuid-ossp");
37
+
38
+            modelBuilder.Entity<LuGroups>(entity =>
39
+            {
40
+                entity.ToTable("lu_groups", "luticate2");
41
+
42
+                entity.HasIndex(e => e.Name)
43
+                    .HasName("lu_groups_name_key")
44
+                    .IsUnique();
45
+
46
+                entity.Property(e => e.Id)
47
+                    .HasColumnName("id")
48
+                    .HasDefaultValueSql("luticate2.lu_sp_generate_uuid('lu_groups'::text)");
49
+
50
+                entity.Property(e => e.Name)
51
+                    .IsRequired()
52
+                    .HasColumnName("name")
53
+                    .HasColumnType("citext");
54
+
55
+                entity.HasOne(d => d.IdNavigation)
56
+                    .WithOne(p => p.LuGroups)
57
+                    .HasForeignKey<LuGroups>(d => d.Id)
58
+                    .OnDelete(DeleteBehavior.ClientSetNull)
59
+                    .HasConstraintName("lu_groups_id_fkey");
60
+            });
61
+
62
+            modelBuilder.Entity<LuGroupsObjects>(entity =>
63
+            {
64
+                entity.HasKey(e => new { e.GroupId, e.ObjectId });
65
+
66
+                entity.ToTable("lu_groups_objects", "luticate2");
67
+
68
+                entity.HasIndex(e => new { e.ObjectId, e.Priority })
69
+                    .HasName("lu_groups_objects_object_id_priority_key")
70
+                    .IsUnique();
71
+
72
+                entity.Property(e => e.GroupId).HasColumnName("group_id");
73
+
74
+                entity.Property(e => e.ObjectId).HasColumnName("object_id");
75
+
76
+                entity.Property(e => e.Priority).HasColumnName("priority");
77
+
78
+                entity.HasOne(d => d.Group)
79
+                    .WithMany(p => p.LuGroupsObjects)
80
+                    .HasForeignKey(d => d.GroupId)
81
+                    .HasConstraintName("lu_groups_objects_group_id_fkey");
82
+
83
+                entity.HasOne(d => d.Object)
84
+                    .WithMany(p => p.LuGroupsObjects)
85
+                    .HasForeignKey(d => d.ObjectId)
86
+                    .OnDelete(DeleteBehavior.ClientSetNull)
87
+                    .HasConstraintName("lu_groups_objects_object_id_fkey");
88
+            });
89
+
90
+            modelBuilder.Entity<LuObjectsMetadata>(entity =>
91
+            {
92
+                entity.ToTable("lu_objects_metadata", "luticate2");
93
+
94
+                entity.Property(e => e.Id)
95
+                    .HasColumnName("id")
96
+                    .HasDefaultValueSql("luticate2.lu_sp_generate_uuid('lu_objects_metadata'::text)");
97
+
98
+                entity.Property(e => e.CreatedAt)
99
+                    .HasColumnName("created_at")
100
+                    .HasColumnType("timestamp with time zone")
101
+                    .HasDefaultValueSql("now()");
102
+
103
+                entity.Property(e => e.UpdatedAt)
104
+                    .HasColumnName("updated_at")
105
+                    .HasColumnType("timestamp with time zone");
106
+            });
107
+
108
+            modelBuilder.Entity<LuUsers>(entity =>
109
+            {
110
+                entity.ToTable("lu_users", "luticate2");
111
+
112
+                entity.HasIndex(e => e.Username)
113
+                    .HasName("lu_users_username_key")
114
+                    .IsUnique();
115
+
116
+                entity.Property(e => e.Id)
117
+                    .HasColumnName("id")
118
+                    .HasDefaultValueSql("luticate2.lu_sp_generate_uuid('lu_users'::text)");
119
+
120
+                entity.Property(e => e.Username)
121
+                    .IsRequired()
122
+                    .HasColumnName("username")
123
+                    .HasColumnType("citext");
124
+
125
+                entity.HasOne(d => d.IdNavigation)
126
+                    .WithOne(p => p.LuUsers)
127
+                    .HasForeignKey<LuUsers>(d => d.Id)
128
+                    .OnDelete(DeleteBehavior.ClientSetNull)
129
+                    .HasConstraintName("lu_users_id_fkey");
130
+            });
131
+        }
132
+    }
133
+}

+ 7
- 0
Luticate2.Auth/Dbo/Auth/LuGroupDbo.cs Просмотреть файл

@@ -0,0 +1,7 @@
1
+namespace Luticate2.Auth.Dbo.Auth
2
+{
3
+    public class LuGroupDbo : LuObjectDbo
4
+    {
5
+        public string Name { get; set; }
6
+    }
7
+}

+ 11
- 0
Luticate2.Auth/Dbo/Auth/LuObjectDbo.cs Просмотреть файл

@@ -0,0 +1,11 @@
1
+using System;
2
+
3
+namespace Luticate2.Auth.Dbo.Auth
4
+{
5
+    public class LuObjectDbo
6
+    {
7
+        public Guid Id { get; set; }
8
+        
9
+        public LuObjectsMetadataDbo Metadata { get; set; }
10
+    }
11
+}

+ 13
- 0
Luticate2.Auth/Dbo/Auth/LuObjectsMetadataDbo.cs Просмотреть файл

@@ -0,0 +1,13 @@
1
+using System;
2
+
3
+namespace Luticate2.Auth.Dbo.Auth
4
+{
5
+    public class LuObjectsMetadataDbo
6
+    {
7
+        public Guid Id { get; set; }
8
+
9
+        public DateTime CreatedAt { get; set; }
10
+
11
+        public DateTime? UpdatedAt { get; set; }
12
+    }
13
+}

+ 0
- 7
Luticate2.Auth/Dbo/Basic/LuAuthOptions.cs Просмотреть файл

@@ -1,7 +0,0 @@
1
-namespace Luticate2.Auth.Dbo.Basic
2
-{
3
-    public class LuAuthOptions
4
-    {
5
-        public string Version { get; set; }
6
-    }
7
-}

+ 50
- 0
Luticate2.Auth/Dbo/Fields/LuFieldDbo.cs Просмотреть файл

@@ -0,0 +1,50 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Linq.Expressions;
5
+using Luticate2.Auth.Business.Fields;
6
+
7
+namespace Luticate2.Auth.Dbo.Fields
8
+{
9
+    public class LuFieldDbo
10
+    {
11
+        public IList<string> Parts { get; set; } = new List<string>();
12
+
13
+        public static LuFieldDbo Make(IEnumerable<string> parts)
14
+        {
15
+            var partialFieldpath = new LuFieldDbo();
16
+            return partialFieldpath.Add(parts);
17
+        }
18
+
19
+        public static LuFieldDbo Make(string path)
20
+        {
21
+            var partialFieldpath = new LuFieldDbo();
22
+            return partialFieldpath.Add(path);
23
+        }
24
+
25
+        public static LuFieldDbo Make(LuFieldDbo path)
26
+        {
27
+            var partialFieldpath = new LuFieldDbo();
28
+            return partialFieldpath.Add(path);
29
+        }
30
+
31
+        public static LuFieldDbo Make<TTypeTo>(Expression<Func<TTypeTo, object>> property)
32
+        {
33
+            var partialFieldpath = new LuFieldDbo();
34
+            return partialFieldpath.Add(property);
35
+        }
36
+
37
+        public LuFieldDbo Copy()
38
+        {
39
+            return new LuFieldDbo
40
+            {
41
+                Parts = Parts.ToList()
42
+            };
43
+        }
44
+        
45
+        public override string ToString()
46
+        {
47
+            return string.Join("/", Parts);
48
+        }
49
+    }
50
+}

+ 9
- 0
Luticate2.Auth/Dbo/Fields/LuPartialFieldsDbo.cs Просмотреть файл

@@ -0,0 +1,9 @@
1
+using System.Collections.Generic;
2
+
3
+namespace Luticate2.Auth.Dbo.Fields
4
+{
5
+    public class LuPartialFieldsDbo
6
+    {
7
+        public IList<LuFieldDbo> Fields { get; set; }
8
+    }
9
+}

+ 1
- 24
Luticate2.Auth/Dbo/LuDboExtensions.cs Просмотреть файл

@@ -1,8 +1,4 @@
1
-using System;
2
-using System.Collections.Generic;
3
-using System.Linq;
4
-using Luticate2.Auth.Dbo.Pagination;
5
-using Luticate2.Auth.Dbo.Result;
1
+using Luticate2.Auth.Dbo.Result;
6 2
 
7 3
 namespace Luticate2.Auth.Dbo
8 4
 {
@@ -12,24 +8,5 @@ namespace Luticate2.Auth.Dbo
12 8
         {
13 9
             return (int) status;
14 10
         }
15
-
16
-        // TODO?
17
-//        public static LuPaginatedDbo<TDbo> To<TDbo>(this LuPaginatedDbo<TDbo> data, Func<List<TDbo>, List<TDbo>> convert)
18
-//        {
19
-//            return new LuPaginatedDbo<TDbo>
20
-//            {
21
-//                Count = data.Count,
22
-//                Data = convert(data.Data)
23
-//            };
24
-//        }
25
-//
26
-//        public static LuPaginatedDbo<TDbo> Select<TDbo>(this LuPaginatedDbo<TDbo> data, Func<TDbo, TDbo> convert)
27
-//        {
28
-//            return new LuPaginatedDbo<TDbo>
29
-//            {
30
-//                Count = data.Count,
31
-//                Data = data.Data.Select(convert).ToList()
32
-//            };
33
-//        }
34 11
     }
35 12
 }

+ 2
- 47
Luticate2.Auth/Dbo/Pagination/LuFilterDbo.cs Просмотреть файл

@@ -1,54 +1,9 @@
1
-using System.Collections.Generic;
1
+using System.Linq.Expressions;
2 2
 
3 3
 namespace Luticate2.Auth.Dbo.Pagination
4 4
 {
5 5
     public class LuFilterDbo
6 6
     {
7
-        public string Query { get; set; }
8
-
9
-        public IDictionary<string, string> Filters { get; set; }
10
-
11
-        public string GetFilterString(string key, string defaultValue)
12
-        {
13
-            if (!Filters.ContainsKey(key))
14
-            {
15
-                return defaultValue;
16
-            }
17
-            return Filters[key];
18
-        }
19
-
20
-        public bool? GetFilterBool(string key, bool? defaultValue)
21
-        {
22
-            var value = GetFilterString(key, "").ToLower();
23
-            if (value == "true")
24
-            {
25
-                return true;
26
-            }
27
-            if (value == "false")
28
-            {
29
-                return false;
30
-            }
31
-            return defaultValue;
32
-        }
33
-
34
-        public int? GetFilterInt(string key, int? defaultValue)
35
-        {
36
-            int v;
37
-            if (int.TryParse(GetFilterString(key, ""), out v))
38
-            {
39
-                return v;
40
-            }
41
-            return defaultValue;
42
-        }
43
-
44
-        public double? GetFilterFloat(string key, double? defaultValue)
45
-        {
46
-            double v;
47
-            if (double.TryParse(GetFilterString(key, ""), out v))
48
-            {
49
-                return v;
50
-            }
51
-            return defaultValue;
52
-        }
7
+        public Expression Expression { get; set; }
53 8
     }
54 9
 }

+ 1
- 1
Luticate2.Auth/Dbo/Pagination/LuOrderByDbo.cs Просмотреть файл

@@ -4,6 +4,6 @@ namespace Luticate2.Auth.Dbo.Pagination
4 4
 {
5 5
     public class LuOrderByDbo
6 6
     {
7
-        public IList<LuOrderByFieldDbo> Fields { get; set; }
7
+        public IList<LuOrderByFieldDbo> OrderByFields { get; set; }
8 8
     }
9 9
 }

+ 11
- 3
Luticate2.Auth/Dbo/Pagination/LuOrderByFieldDbo.cs Просмотреть файл

@@ -1,9 +1,17 @@
1
-namespace Luticate2.Auth.Dbo.Pagination
1
+using Luticate2.Auth.Dbo.Fields;
2
+
3
+namespace Luticate2.Auth.Dbo.Pagination
2 4
 {
3 5
     public class LuOrderByFieldDbo
4 6
     {
5
-        public string Name { get; set; }
7
+        public LuFieldDbo Field { get; set; }
8
+
9
+        public bool Asc { get; set; } = true;
6 10
 
7
-        public bool Asc { get; set; }
11
+        public override string ToString()
12
+        {
13
+            var asc = Asc ? "ASC" : "DESC";
14
+            return $"{string.Join(".", Field)}:{asc}";
15
+        }
8 16
     }
9 17
 }

+ 7
- 0
Luticate2.Auth/Dbo/PartialObjectCopier/LuPartialObjectCopierOptions.cs Просмотреть файл

@@ -0,0 +1,7 @@
1
+namespace Luticate2.Auth.Dbo.PartialObjectCopier
2
+{
3
+    public class LuPartialObjectCopierOptions
4
+    {
5
+        
6
+    }
7
+}

+ 18
- 0
Luticate2.Auth/Interfaces/ILuCrud.cs Просмотреть файл

@@ -0,0 +1,18 @@
1
+using System.Collections.Generic;
2
+using Luticate2.Auth.Dbo.Fields;
3
+using Luticate2.Auth.Dbo.Pagination;
4
+using Luticate2.Auth.Dbo.Result;
5
+
6
+namespace Luticate2.Auth.Interfaces
7
+{
8
+    public interface ILuCrud<TDbo>
9
+    {
10
+        LuResult<IList<TDbo>> Create(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos);
11
+        
12
+        LuResult<LuPaginatedDbo<TDbo>> Read(LuPartialFieldsDbo partialResponse, LuPaginatedParamsDbo paginationParams);
13
+        
14
+        LuResult<IList<TDbo>> Update(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos);
15
+        
16
+        LuResult<IList<TDbo>> Delete(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos);
17
+    }
18
+}

+ 12
- 0
Luticate2.Auth/Interfaces/ILuFieldsExpressions.cs Просмотреть файл

@@ -0,0 +1,12 @@
1
+using System;
2
+using System.Linq.Expressions;
3
+using Luticate2.Auth.Dbo.Fields;
4
+using Luticate2.Auth.Dbo.Result;
5
+
6
+namespace Luticate2.Auth.Interfaces
7
+{
8
+    public interface ILuFieldsExpressions<TDbo, TModel>
9
+    {
10
+        LuResult<Expression<Func<TType1, object>>> GetExpression<TType1>(Expression<Func<TType1, TModel>> modelProperty, LuFieldDbo field);
11
+    }
12
+}

+ 14
- 0
Luticate2.Auth/Interfaces/ILuOrderByObjectType.cs Просмотреть файл

@@ -0,0 +1,14 @@
1
+using System;
2
+using System.Linq;
3
+using System.Linq.Expressions;
4
+using Luticate2.Auth.Dbo.Pagination;
5
+using Luticate2.Auth.Dbo.Result;
6
+
7
+namespace Luticate2.Auth.Interfaces
8
+{
9
+    public interface ILuOrderByObjectType<TType>
10
+    {
11
+        LuResult<IQueryable<TModel>> OrderByField<TModel, TType2>(Expression<Func<TModel, TType2>> modelProperty,
12
+            LuOrderByFieldDbo orderByfield, IQueryable<TModel> queryable);
13
+    }
14
+}

+ 13
- 0
Luticate2.Auth/Interfaces/ILuPartialObjectCopier.cs Просмотреть файл

@@ -0,0 +1,13 @@
1
+using Luticate2.Auth.Dbo.Fields;
2
+using Luticate2.Auth.Dbo.PartialObjectCopier;
3
+using Luticate2.Auth.Dbo.Result;
4
+
5
+namespace Luticate2.Auth.Interfaces
6
+{
7
+    public interface ILuPartialObjectCopier<TTypeFrom, TTypeTo>
8
+    {
9
+        LuResult<TTypeTo> Copy(LuFieldDbo path, LuPartialFieldsDbo fields, TTypeFrom dboFrom, TTypeTo dboTo, LuPartialObjectCopierOptions options);
10
+
11
+        LuResult<TTypeTo> Copy(LuPartialFieldsDbo fields, TTypeFrom dboFrom, TTypeTo dboTo, LuPartialObjectCopierOptions options);
12
+    }
13
+}

+ 19
- 3
Luticate2.Auth/Luticate2.Auth.csproj Просмотреть файл

@@ -1,9 +1,25 @@
1 1
 <Project Sdk="Microsoft.NET.Sdk">
2 2
   <PropertyGroup>
3
-    <TargetFramework>netstandard2.0</TargetFramework>
3
+    <TargetFramework>netcoreapp2.1</TargetFramework>
4 4
   </PropertyGroup>
5 5
   <ItemGroup>
6
-    <Folder Include="Business" />
7
-    <Folder Include="Interfaces" />
6
+    <Folder Include="Business\Serializers" />
7
+    <Folder Include="DataAccess\Models" />
8
+  </ItemGroup>
9
+  <ItemGroup>
10
+    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="2.8.2" />
11
+    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.0" />
12
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.0" />
13
+    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
14
+    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.0" />
15
+    <PackageReference Include="PartialResponse.Core" Version="2.0.0" />
16
+  </ItemGroup>
17
+  <ItemGroup>
18
+    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.2" />
19
+  </ItemGroup>
20
+  <ItemGroup>
21
+    <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
22
+      <HintPath>..\..\..\..\.nuget\packages\newtonsoft.json\10.0.1\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath>
23
+    </Reference>
8 24
   </ItemGroup>
9 25
 </Project>

+ 1
- 1
Luticate2.Mvc.Auth.WebApiSample/Luticate2.Mvc.Auth.WebApiSample.csproj Просмотреть файл

@@ -6,7 +6,7 @@
6 6
     <Folder Include="wwwroot\" />
7 7
   </ItemGroup>
8 8
   <ItemGroup>
9
-    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
9
+    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.8" />
10 10
   </ItemGroup>
11 11
   <ItemGroup>
12 12
     <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />

+ 1
- 1
Luticate2.Mvc.Auth/Luticate2.Mvc.Auth.csproj Просмотреть файл

@@ -1,7 +1,7 @@
1 1
 <Project Sdk="Microsoft.NET.Sdk">
2 2
 
3 3
     <PropertyGroup>
4
-        <TargetFramework>netstandard2.0</TargetFramework>
4
+        <TargetFramework>netcoreapp2.0</TargetFramework>
5 5
     </PropertyGroup>
6 6
 
7 7
 </Project>

+ 35
- 0
luticate2.sln.DotSettings.user Просмотреть файл

@@ -0,0 +1,35 @@
1
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ABusiness_002Fd_003AAuth_002Ff_003ALuGroupsBusiness_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
3
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ABusiness_002Fd_003AFields_002Ff_003ALuFieldsExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
4
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ABusiness_002Fd_003APartialObjectCopier_002Ff_003ALuPartialObjectCopier_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
5
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ABusiness_002Fd_003APartialObjectCopier_002Ff_003ALuPartialObjectCopierGroups_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
6
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ABusiness_002Fd_003APartialObjectCopier_002Ff_003ALuPartialObjectCopierObjectsMetadata_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
7
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ABusiness_002Ff_003ALuExpressionUtils_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
8
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ADbo_002Fd_003AAuth_002Ff_003ALuGroupDbo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
9
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=11727D2F_002DE2EE_002D4FD5_002DBEC4_002DC22B5B0D38A2_002Fd_003ADbo_002Fd_003AAuth_002Ff_003ALuObjectsMetadata_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
10
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=65809E11_002D3C5B_002D4641_002D9710_002DE8EEF47A72E1_002Fd_003ACommands_002Ff_003AListCommand_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
11
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=65809E11_002D3C5B_002D4641_002D9710_002DE8EEF47A72E1_002Ff_003AProgram_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
12
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentBaseAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003F64_003F902a0698_003FArgumentBaseAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
13
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentDefinition_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003F48_003Fdae98adf_003FArgumentDefinition_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
14
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003Fd9_003F5898099c_003FArgumentType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
15
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentValueAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003F0f_003Ff70f89fc_003FArgumentValueAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
16
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentValueFlags_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003Fc5_003Fdc1a89c7_003FArgumentValueFlags_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
17
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACollectionExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F74C8172C_002DE9D1_002D4BB9_002DBA38_002DB75C870811D2_003Fa7_003F332ae189_003FCollectionExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
18
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACommandAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003F8c_003F0f6ac0f3_003FCommandAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
19
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACommandResult_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003F05_003F1a20fe66_003FCommandResult_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
20
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACommand_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003F60_003F54980336_003FCommand_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
21
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADbSet_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F406635BB_002DC0DC_002D4AE8_002D9B6C_002D783FB3A661DB_003F29_003Fd4a20fe1_003FDbSet_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
22
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEntityFrameworkQueryableExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F406635BB_002DC0DC_002D4AE8_002D9B6C_002D783FB3A661DB_003Fc3_003Fe9584849_003FEntityFrameworkQueryableExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
23
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerableExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F406635BB_002DC0DC_002D4AE8_002D9B6C_002D783FB3A661DB_003Fe6_003F156d683f_003FEnumerableExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
24
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FE9E7BFFA_002D7295_002D472B_002DA90E_002D02CE460D5C59_003F63_003F8dea892b_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
25
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0E1B27A4_002D6035_002D47D9_002DA041_002DCEF439F84C41_003F2e_003F9d4c8d59_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
26
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExecutionTimer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F724F386D_002D8F5B_002D4395_002DA7FA_002D46C7A3A38A2A_003Fb4_003F01ff0251_003FExecutionTimer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
27
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExpression_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F74C8172C_002DE9D1_002D4BB9_002DBA38_002DB75C870811D2_003F0d_003Fe5150c41_003FExpression_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
28
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFields_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9AE94C13_002D307D_002D4B81_002D9C49_002D042C5D639F18_003Fc1_003F78441bb9_003FFields_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
29
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AICommand_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003Fdc_003F995e2262_003FICommand_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
30
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALoggingServiceCollectionExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8CF7D9CF_002DDEC7_002D4909_002D9A0A_002D744E024801B5_003F5c_003Fb20d4f16_003FLoggingServiceCollectionExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
31
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMethodBase_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0E1B27A4_002D6035_002D47D9_002DA041_002DCEF439F84C41_003Fbd_003Ffd3a8b29_003FMethodBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
32
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANamedArgumentAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003FBA7C3D01_002D2007_002D4710_002D95AB_002D341647F324E9_003Fde_003F366d7bbe_003FNamedArgumentAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
33
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F711AF2B2_002DC9DB_002D4B65_002DB7EA_002DB21A353C3B37_003F39_003F53296e13_003FQueryable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
34
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueryCompiler_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F406635BB_002DC0DC_002D4AE8_002D9B6C_002D783FB3A661DB_003F8f_003Fc4fa4ffe_003FQueryCompiler_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
35
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002ERider2018_002E1_003Fconfig_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0E1B27A4_002D6035_002D47D9_002DA041_002DCEF439F84C41_003Fd0_003Fedac82f9_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

Загрузка…
Отмена
Сохранить