Skip to content

Commit 570e15d

Browse files
authored
Merge pull request #1 from I-RzR-I/feature/AddNewTests
Change property mapper. Add tests for simple select query.
2 parents 9c61696 + ce3b55f commit 570e15d

File tree

20 files changed

+543
-44
lines changed

20 files changed

+543
-44
lines changed

docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### **1.0.1.8361**
2+
-> Change property mapper (map by property/column name);<br />
3+
-> Add EF DbContextExtension (that load neccessary information);<br />
4+
-> Add tests for simple select query and adjust mapper.<br />
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// ***********************************************************************
2+
// Assembly : RzR.Shared.Entity.DbObjectExecutor.Attribute
3+
// Author : RzR
4+
// Created On : 2024-04-08 08:40
5+
//
6+
// Last Modified By : RzR
7+
// Last Modified On : 2024-04-08 22:10
8+
// ***********************************************************************
9+
// <copyright file="DbConnectionExtensions.cs" company="">
10+
// Copyright (c) RzR. All rights reserved.
11+
// </copyright>
12+
//
13+
// <summary>
14+
// </summary>
15+
// ***********************************************************************
16+
17+
#region U S A G E S
18+
19+
using DbObjectExecutor.Attribute.Enums;
20+
using System.Data.Common;
21+
using System.Runtime.CompilerServices;
22+
23+
#endregion
24+
25+
[assembly: InternalsVisibleTo("DbObjectExecutor.Imp.EntityFramework")]
26+
27+
namespace DbObjectExecutor.Attribute.Extensions
28+
{
29+
/// -------------------------------------------------------------------------------------------------
30+
/// <summary>
31+
/// A database connection extensions.
32+
/// </summary>
33+
/// =================================================================================================
34+
internal static class DbConnectionExtensions
35+
{
36+
/// -------------------------------------------------------------------------------------------------
37+
/// <summary>
38+
/// A DbConnection extension method that gets database provider type.
39+
/// </summary>
40+
/// <param name="connection">The connection to act on.</param>
41+
/// <returns>
42+
/// The database provider type.
43+
/// </returns>
44+
/// =================================================================================================
45+
internal static DbProviderType GetDbProviderType(this DbConnection connection)
46+
=> connection.GetType().Name switch
47+
{
48+
"OracleConnection" => DbProviderType.Oracle,
49+
"MySqlConnection" => DbProviderType.MySql,
50+
"NpgsqlConnection" => DbProviderType.PostgreSql,
51+
"SqliteConnection" => DbProviderType.SqLite,
52+
"SqlServerConnection" => DbProviderType.MsSql,
53+
_ => DbProviderType.MsSql
54+
};
55+
}
56+
}

src/DbObjectExecutor.Imp.EntityFramework/DbContextExtension.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using DbObjectExecutor.Abstractions;
2020
using DbObjectExecutor.Attribute.Builders;
2121
using DbObjectExecutor.Attribute.Enums;
22+
using DbObjectExecutor.Attribute.Extensions;
2223
using DbObjectExecutor.Attribute.Models.Result;
2324
using DbObjectExecutor.Builders;
2425
using DbObjectExecutor.Enums;
@@ -87,5 +88,33 @@ public static BuildRequestResultDto LoadDbObject(this DbContext ctx, DbProviderT
8788

8889
return procedureRequest;
8990
}
91+
92+
/// -------------------------------------------------------------------------------------------------
93+
/// <summary>
94+
/// A DbContext extension method that loads database object.
95+
/// </summary>
96+
/// <param name="ctx">The ctx to act on.</param>
97+
/// <param name="requestObjectInfo">Information describing the request object.</param>
98+
/// <param name="requestObjectInfoType">Type of the request object information.</param>
99+
/// <param name="dbObjectName">(Optional) Name of the database object.</param>
100+
/// <param name="commandType">(Optional) Type of the command.</param>
101+
/// <returns>
102+
/// The database object.
103+
/// </returns>
104+
/// =================================================================================================
105+
public static BuildRequestResultDto LoadDbObject(this DbContext ctx, object requestObjectInfo,
106+
Type requestObjectInfoType, string dbObjectName = null, DbExecutorType commandType = DbExecutorType.Undefined)
107+
{
108+
var connection = ctx.Database.GetDbConnection();
109+
var transaction = ctx.Database.CurrentTransaction?.GetDbTransaction();
110+
var dbProviderType = connection.GetDbProviderType();
111+
112+
var procedureRequest = DbObjectExecutorRequestBuilder.BuildRequest(dbProviderType, connection, requestObjectInfo,
113+
requestObjectInfoType, dbObjectName, commandType, true);
114+
115+
procedureRequest.DbObjectBuilder.UseTransaction(transaction);
116+
117+
return procedureRequest;
118+
}
90119
}
91120
}

src/DbObjectExecutor.Imp.EntityFramework/DbObjectExecutor.Imp.EntityFramework.csproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@
3636
<ItemGroup>
3737
<Compile Include="..\shared\GeneralAssemblyInfo.cs" Link="Properties\GeneralAssemblyInfo.cs" />
3838
</ItemGroup>
39-
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'
40-
Or '$(TargetFramework)' == 'netstandard2.1'
41-
Or '$(TargetFramework)' == 'net5.0' ">
42-
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.32"/>
39+
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' &#xD;&#xA; Or '$(TargetFramework)' == 'netstandard2.1' &#xD;&#xA; Or '$(TargetFramework)' == 'net5.0' ">
40+
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.32" />
4341
</ItemGroup>
4442

4543
<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">

src/DbObjectExecutor/Builders/DbObjectBuilder.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
using System.Threading;
2828
using System.Threading.Tasks;
2929

30+
// ReSharper disable PossibleNullReferenceException
3031
// ReSharper disable MethodOverloadWithOptionalParameter
3132
// ReSharper disable PossibleIntendedRethrow
3233
//
@@ -106,7 +107,7 @@ public IDbObjectCommon UseTransaction(DbTransaction transaction = null)
106107
OpenConnection();
107108

108109
var trans = transaction.IsNull()
109-
? _dbCommand.Connection.BeginTransaction(IsolationLevel.ReadUncommitted)
110+
? _dbCommand.Connection!.BeginTransaction(IsolationLevel.ReadUncommitted)
110111
: transaction;
111112
_dbCommand.Transaction = trans;
112113

@@ -116,17 +117,17 @@ public IDbObjectCommon UseTransaction(DbTransaction transaction = null)
116117
/// <inheritdoc/>
117118
public IDbObjectCommon CommitTransaction()
118119
{
119-
if (_dbCommand.Connection.State.IsOpen())
120-
_dbCommand.Transaction.Commit();
120+
if (_dbCommand.Connection!.State.IsOpen())
121+
_dbCommand.Transaction!.Commit();
121122

122123
return this;
123124
}
124125

125126
/// <inheritdoc/>
126127
public IDbObjectCommon RollBackTransaction()
127128
{
128-
if (_dbCommand.Connection.State.IsOpen())
129-
_dbCommand.Transaction.Rollback();
129+
if (_dbCommand.Connection!.State.IsOpen())
130+
_dbCommand.Transaction!.Rollback();
130131

131132
return this;
132133
}
@@ -399,7 +400,7 @@ public async Task ExecuteScalarAsync<T>(Action<T> action, CancellationToken canc
399400
/// =================================================================================================
400401
private bool OpenConnection()
401402
{
402-
if (_dbCommand.Connection.State.IsClose())
403+
if (_dbCommand.Connection!.State.IsClose())
403404
{
404405
_dbCommand.Connection.Open();
405406

@@ -423,7 +424,7 @@ private bool OpenConnection()
423424
/// =================================================================================================
424425
private async Task<bool> OpenConnectionAsync(CancellationToken cancellationToken)
425426
{
426-
if (_dbCommand.Connection.State.IsClose())
427+
if (_dbCommand.Connection!.State.IsClose())
427428
{
428429
await _dbCommand.Connection.OpenAsync(cancellationToken).ConfigureAwait(false);
429430

src/DbObjectExecutor/DbObjectExecutor.csproj

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,7 @@
5353
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
5454
</ItemGroup>
5555

56-
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'
57-
Or '$(TargetFramework)' == 'net5.0'
58-
Or '$(TargetFramework)' == 'net6.0'
59-
Or '$(TargetFramework)' == 'net7.0'
60-
Or '$(TargetFramework)' == 'net8.0'">
56+
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'&#xD;&#xA; Or '$(TargetFramework)' == 'net5.0'&#xD;&#xA; Or '$(TargetFramework)' == 'net6.0'&#xD;&#xA; Or '$(TargetFramework)' == 'net7.0'&#xD;&#xA; Or '$(TargetFramework)' == 'net8.0'">
6157
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.32" />
6258
</ItemGroup>
6359
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// ***********************************************************************
2+
// Assembly : RzR.Shared.Entity.DbObjectExecutor
3+
// Author : RzR
4+
// Created On : 2024-04-07 22:30
5+
//
6+
// Last Modified By : RzR
7+
// Last Modified On : 2024-04-08 22:22
8+
// ***********************************************************************
9+
// <copyright file="EnumerableExtensions.cs" company="">
10+
// Copyright (c) RzR. All rights reserved.
11+
// </copyright>
12+
//
13+
// <summary>
14+
// </summary>
15+
// ***********************************************************************
16+
17+
#region U S A G E S
18+
19+
using System.Collections.Generic;
20+
using System.Linq;
21+
22+
#endregion
23+
24+
namespace DbObjectExecutor.Extensions
25+
{
26+
/// <summary>
27+
/// Enumerable extensions
28+
/// </summary>
29+
internal static class EnumerableExtensions
30+
{
31+
/// <summary>
32+
/// Format list to list with item index
33+
/// </summary>
34+
/// <param name="self">Input list</param>
35+
/// <returns></returns>
36+
/// <typeparam name="T">List type</typeparam>
37+
/// <remarks></remarks>
38+
internal static IEnumerable<(T item, int index)> WithIndex<T>(this IEnumerable<T> self)
39+
=> self?.Select((item, index) => (item, index)) ?? new List<(T, int)>();
40+
}
41+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// ***********************************************************************
2+
// Assembly : RzR.Shared.Entity.DbObjectExecutor
3+
// Author : RzR
4+
// Created On : 2024-04-07 23:54
5+
//
6+
// Last Modified By : RzR
7+
// Last Modified On : 2024-04-07 23:54
8+
// ***********************************************************************
9+
// <copyright file="PropertyMapDto.cs" company="">
10+
// Copyright (c) RzR. All rights reserved.
11+
// </copyright>
12+
//
13+
// <summary>
14+
// </summary>
15+
// ***********************************************************************
16+
17+
using System.Reflection;
18+
// ReSharper disable PropertyCanBeMadeInitOnly.Global
19+
20+
namespace DbObjectExecutor.Mapper.Models
21+
{
22+
/// -------------------------------------------------------------------------------------------------
23+
/// <summary>
24+
/// A property map data transfer object.
25+
/// </summary>
26+
/// =================================================================================================
27+
internal class PropertyMapDto
28+
{
29+
/// -------------------------------------------------------------------------------------------------
30+
/// <summary>
31+
/// Gets or sets the name of the source.
32+
/// </summary>
33+
/// <value>
34+
/// The name of the source.
35+
/// </value>
36+
/// =================================================================================================
37+
public string SourceName { get; set; }
38+
39+
/// -------------------------------------------------------------------------------------------------
40+
/// <summary>
41+
/// Gets or sets the name of the attribute.
42+
/// </summary>
43+
/// <value>
44+
/// The name of the attribute.
45+
/// </value>
46+
/// =================================================================================================
47+
public string AttributeName { get; set; }
48+
49+
/// -------------------------------------------------------------------------------------------------
50+
/// <summary>
51+
/// Gets or sets a value indicating whether this object is in response.
52+
/// </summary>
53+
/// <value>
54+
/// True if this object is in response, false if not.
55+
/// </value>
56+
/// =================================================================================================
57+
public bool IsInResponse { get; set; }
58+
59+
/// -------------------------------------------------------------------------------------------------
60+
/// <summary>
61+
/// Gets or sets the property.
62+
/// </summary>
63+
/// <value>
64+
/// The property.
65+
/// </value>
66+
/// =================================================================================================
67+
public PropertyInfo Property { get; set; }
68+
}
69+
}

src/DbObjectExecutor/Mapper/ReaderMapper.cs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
using DbObjectExecutor.Extensions;
2020
using DbObjectExecutor.Helpers;
21+
using DbObjectExecutor.Mapper.Models;
2122
using System;
2223
using System.Collections.Concurrent;
2324
using System.Collections.Generic;
2425
using System.Data.Common;
2526
using System.Linq;
26-
using System.Reflection;
2727
using System.Threading;
2828
using System.Threading.Tasks;
2929

@@ -206,40 +206,48 @@ private ReaderProperty[] MapColumnsToProperties()
206206
var sourceType = typeof(T);
207207
var columns = new string[_reader.FieldCount];
208208

209-
var props = sourceType.GetPropertyInfos().ToArray();
209+
var sourcePropertyInfo = new List<PropertyMapDto>(sourceType.GetPropertyInfos().WithIndex()
210+
.Select(x => new PropertyMapDto()
211+
{
212+
SourceName = x.item.Name,
213+
Property = x.item,
214+
AttributeName = DbObjectColumnAttributeHelper.GetDbObjectColumnName(x.item),
215+
IsInResponse = false
216+
}));
210217

211-
for (var i = 0; i < _reader.FieldCount; ++i)
212-
{
213-
var attributeColumnName = DbObjectColumnAttributeHelper.GetDbObjectColumnName(props[i]);
214218

215-
columns[i] = attributeColumnName.IsNullOrEmpty() ? _reader.GetName(i) : attributeColumnName;
219+
for (var i = 0; i < _reader.FieldCount; i++)
220+
{
221+
var columnName = _reader.GetName(i);
222+
columns[i] = columnName;
223+
var sourceProp = sourcePropertyInfo.FirstOrDefault(x => x.AttributeName == columnName);
224+
if (sourceProp.IsNotNull())
225+
{
226+
sourceProp!.IsInResponse = true;
227+
}
216228
}
217229

230+
// Create result property list hash
218231
var propKey = ComputePropertyKey(columns);
219232
if (PropertiesCache.TryGetValue(propKey, out var propValue))
220233
return propValue;
221234

222-
var properties = new List<ReaderProperty>(columns.Length);
235+
var properties = new ReaderProperty[columns.Length];
223236
for (var i = 0; i < columns.Length; i++)
224237
{
225-
PropertyInfo prop;
226-
var propAttributeSource = sourceType.GetPropertyByName(columns[i].Replace("_", ""));
227-
var propSource = sourceType.GetPropertyByName(props[i].Name.Replace("_", ""));
228-
229-
if (propSource.IsNull() && propAttributeSource.IsNull())
230-
continue;
231-
else
232-
prop = propSource.IsNull() ? propAttributeSource : propSource;
233-
234-
var setter = (Action<object, object>)ExpressionBuildHelper.BuildPropertySetter(prop);
235-
236-
properties.Add(new ReaderProperty { Idx = i, Setter = setter, Name = prop.Name });
238+
var property = sourcePropertyInfo.FirstOrDefault(x => x.AttributeName == columns[i].Replace("_", "")
239+
&& x.IsInResponse.IsTrue());
240+
if (property.IsNotNull())
241+
{
242+
var setter = (Action<object, object>)ExpressionBuildHelper.BuildPropertySetter(property!.Property);
243+
244+
properties[i] = new ReaderProperty { Idx = i, Setter = setter, Name = property.SourceName };
245+
}
237246
}
238247

239-
var propertiesArray = properties.ToArray();
240-
PropertiesCache[propKey] = propertiesArray;
248+
PropertiesCache[propKey] = properties;
241249

242-
return propertiesArray;
250+
return properties;
243251
}
244252
}
245253
}

src/shared/GeneralAssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838
[assembly: AssemblyMetadata("ContactName", "RzR")]
3939
[assembly: AssemblyMetadata("ContactEmail", "ddpRzR@hotmail.com")]
4040
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
41-
[assembly: AssemblyVersion("1.0.0.0")]
42-
[assembly: AssemblyFileVersion("1.0.0.0")]
43-
[assembly: AssemblyInformationalVersion("1.0.0.0")]
41+
[assembly: AssemblyVersion("1.0.1.8361")]
42+
[assembly: AssemblyFileVersion("1.0.1.8361")]
43+
[assembly: AssemblyInformationalVersion("1.0.1.8361")]

0 commit comments

Comments
 (0)