Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### **1.0.1.8361**
-> Change property mapper (map by property/column name);<br />
-> Add EF DbContextExtension (that load neccessary information);<br />
-> Add tests for simple select query and adjust mapper.<br />
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// ***********************************************************************
// Assembly : RzR.Shared.Entity.DbObjectExecutor.Attribute
// Author : RzR
// Created On : 2024-04-08 08:40
//
// Last Modified By : RzR
// Last Modified On : 2024-04-08 22:10
// ***********************************************************************
// <copyright file="DbConnectionExtensions.cs" company="">
// Copyright (c) RzR. All rights reserved.
// </copyright>
//
// <summary>
// </summary>
// ***********************************************************************

#region U S A G E S

using DbObjectExecutor.Attribute.Enums;
using System.Data.Common;
using System.Runtime.CompilerServices;

#endregion

[assembly: InternalsVisibleTo("DbObjectExecutor.Imp.EntityFramework")]

namespace DbObjectExecutor.Attribute.Extensions
{
/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A database connection extensions.
/// </summary>
/// =================================================================================================
internal static class DbConnectionExtensions
{
/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A DbConnection extension method that gets database provider type.
/// </summary>
/// <param name="connection">The connection to act on.</param>
/// <returns>
/// The database provider type.
/// </returns>
/// =================================================================================================
internal static DbProviderType GetDbProviderType(this DbConnection connection)
=> connection.GetType().Name switch
{
"OracleConnection" => DbProviderType.Oracle,
"MySqlConnection" => DbProviderType.MySql,
"NpgsqlConnection" => DbProviderType.PostgreSql,
"SqliteConnection" => DbProviderType.SqLite,
"SqlServerConnection" => DbProviderType.MsSql,
_ => DbProviderType.MsSql
};
}
}
29 changes: 29 additions & 0 deletions src/DbObjectExecutor.Imp.EntityFramework/DbContextExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using DbObjectExecutor.Abstractions;
using DbObjectExecutor.Attribute.Builders;
using DbObjectExecutor.Attribute.Enums;
using DbObjectExecutor.Attribute.Extensions;
using DbObjectExecutor.Attribute.Models.Result;
using DbObjectExecutor.Builders;
using DbObjectExecutor.Enums;
Expand Down Expand Up @@ -87,5 +88,33 @@ public static BuildRequestResultDto LoadDbObject(this DbContext ctx, DbProviderT

return procedureRequest;
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A DbContext extension method that loads database object.
/// </summary>
/// <param name="ctx">The ctx to act on.</param>
/// <param name="requestObjectInfo">Information describing the request object.</param>
/// <param name="requestObjectInfoType">Type of the request object information.</param>
/// <param name="dbObjectName">(Optional) Name of the database object.</param>
/// <param name="commandType">(Optional) Type of the command.</param>
/// <returns>
/// The database object.
/// </returns>
/// =================================================================================================
public static BuildRequestResultDto LoadDbObject(this DbContext ctx, object requestObjectInfo,
Type requestObjectInfoType, string dbObjectName = null, DbExecutorType commandType = DbExecutorType.Undefined)
{
var connection = ctx.Database.GetDbConnection();
var transaction = ctx.Database.CurrentTransaction?.GetDbTransaction();
var dbProviderType = connection.GetDbProviderType();

var procedureRequest = DbObjectExecutorRequestBuilder.BuildRequest(dbProviderType, connection, requestObjectInfo,
requestObjectInfoType, dbObjectName, commandType, true);

procedureRequest.DbObjectBuilder.UseTransaction(transaction);

return procedureRequest;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@
<ItemGroup>
<Compile Include="..\shared\GeneralAssemblyInfo.cs" Link="Properties\GeneralAssemblyInfo.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'
Or '$(TargetFramework)' == 'netstandard2.1'
Or '$(TargetFramework)' == 'net5.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.32"/>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' &#xD;&#xA; Or '$(TargetFramework)' == 'netstandard2.1' &#xD;&#xA; Or '$(TargetFramework)' == 'net5.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.32" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
Expand Down
15 changes: 8 additions & 7 deletions src/DbObjectExecutor/Builders/DbObjectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using System.Threading;
using System.Threading.Tasks;

// ReSharper disable PossibleNullReferenceException
// ReSharper disable MethodOverloadWithOptionalParameter
// ReSharper disable PossibleIntendedRethrow
//
Expand Down Expand Up @@ -106,7 +107,7 @@ public IDbObjectCommon UseTransaction(DbTransaction transaction = null)
OpenConnection();

var trans = transaction.IsNull()
? _dbCommand.Connection.BeginTransaction(IsolationLevel.ReadUncommitted)
? _dbCommand.Connection!.BeginTransaction(IsolationLevel.ReadUncommitted)
: transaction;
_dbCommand.Transaction = trans;

Expand All @@ -116,17 +117,17 @@ public IDbObjectCommon UseTransaction(DbTransaction transaction = null)
/// <inheritdoc/>
public IDbObjectCommon CommitTransaction()
{
if (_dbCommand.Connection.State.IsOpen())
_dbCommand.Transaction.Commit();
if (_dbCommand.Connection!.State.IsOpen())
_dbCommand.Transaction!.Commit();

return this;
}

/// <inheritdoc/>
public IDbObjectCommon RollBackTransaction()
{
if (_dbCommand.Connection.State.IsOpen())
_dbCommand.Transaction.Rollback();
if (_dbCommand.Connection!.State.IsOpen())
_dbCommand.Transaction!.Rollback();

return this;
}
Expand Down Expand Up @@ -399,7 +400,7 @@ public async Task ExecuteScalarAsync<T>(Action<T> action, CancellationToken canc
/// =================================================================================================
private bool OpenConnection()
{
if (_dbCommand.Connection.State.IsClose())
if (_dbCommand.Connection!.State.IsClose())
{
_dbCommand.Connection.Open();

Expand All @@ -423,7 +424,7 @@ private bool OpenConnection()
/// =================================================================================================
private async Task<bool> OpenConnectionAsync(CancellationToken cancellationToken)
{
if (_dbCommand.Connection.State.IsClose())
if (_dbCommand.Connection!.State.IsClose())
{
await _dbCommand.Connection.OpenAsync(cancellationToken).ConfigureAwait(false);

Expand Down
6 changes: 1 addition & 5 deletions src/DbObjectExecutor/DbObjectExecutor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,7 @@
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'
Or '$(TargetFramework)' == 'net5.0'
Or '$(TargetFramework)' == 'net6.0'
Or '$(TargetFramework)' == 'net7.0'
Or '$(TargetFramework)' == 'net8.0'">
<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'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.32" />
</ItemGroup>
</Project>
41 changes: 41 additions & 0 deletions src/DbObjectExecutor/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// ***********************************************************************
// Assembly : RzR.Shared.Entity.DbObjectExecutor
// Author : RzR
// Created On : 2024-04-07 22:30
//
// Last Modified By : RzR
// Last Modified On : 2024-04-08 22:22
// ***********************************************************************
// <copyright file="EnumerableExtensions.cs" company="">
// Copyright (c) RzR. All rights reserved.
// </copyright>
//
// <summary>
// </summary>
// ***********************************************************************

#region U S A G E S

using System.Collections.Generic;
using System.Linq;

#endregion

namespace DbObjectExecutor.Extensions
{
/// <summary>
/// Enumerable extensions
/// </summary>
internal static class EnumerableExtensions
{
/// <summary>
/// Format list to list with item index
/// </summary>
/// <param name="self">Input list</param>
/// <returns></returns>
/// <typeparam name="T">List type</typeparam>
/// <remarks></remarks>
internal static IEnumerable<(T item, int index)> WithIndex<T>(this IEnumerable<T> self)
=> self?.Select((item, index) => (item, index)) ?? new List<(T, int)>();
}
}
69 changes: 69 additions & 0 deletions src/DbObjectExecutor/Mapper/Models/PropertyMapDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// ***********************************************************************
// Assembly : RzR.Shared.Entity.DbObjectExecutor
// Author : RzR
// Created On : 2024-04-07 23:54
//
// Last Modified By : RzR
// Last Modified On : 2024-04-07 23:54
// ***********************************************************************
// <copyright file="PropertyMapDto.cs" company="">
// Copyright (c) RzR. All rights reserved.
// </copyright>
//
// <summary>
// </summary>
// ***********************************************************************

using System.Reflection;
// ReSharper disable PropertyCanBeMadeInitOnly.Global

namespace DbObjectExecutor.Mapper.Models
{
/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A property map data transfer object.
/// </summary>
/// =================================================================================================
internal class PropertyMapDto
{
/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets the name of the source.
/// </summary>
/// <value>
/// The name of the source.
/// </value>
/// =================================================================================================
public string SourceName { get; set; }

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets the name of the attribute.
/// </summary>
/// <value>
/// The name of the attribute.
/// </value>
/// =================================================================================================
public string AttributeName { get; set; }

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets a value indicating whether this object is in response.
/// </summary>
/// <value>
/// True if this object is in response, false if not.
/// </value>
/// =================================================================================================
public bool IsInResponse { get; set; }

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Gets or sets the property.
/// </summary>
/// <value>
/// The property.
/// </value>
/// =================================================================================================
public PropertyInfo Property { get; set; }
}
}
52 changes: 30 additions & 22 deletions src/DbObjectExecutor/Mapper/ReaderMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

using DbObjectExecutor.Extensions;
using DbObjectExecutor.Helpers;
using DbObjectExecutor.Mapper.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

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

var props = sourceType.GetPropertyInfos().ToArray();
var sourcePropertyInfo = new List<PropertyMapDto>(sourceType.GetPropertyInfos().WithIndex()
.Select(x => new PropertyMapDto()
{
SourceName = x.item.Name,
Property = x.item,
AttributeName = DbObjectColumnAttributeHelper.GetDbObjectColumnName(x.item),
IsInResponse = false
}));

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

columns[i] = attributeColumnName.IsNullOrEmpty() ? _reader.GetName(i) : attributeColumnName;
for (var i = 0; i < _reader.FieldCount; i++)
{
var columnName = _reader.GetName(i);
columns[i] = columnName;
var sourceProp = sourcePropertyInfo.FirstOrDefault(x => x.AttributeName == columnName);
if (sourceProp.IsNotNull())
{
sourceProp!.IsInResponse = true;
}
}

// Create result property list hash
var propKey = ComputePropertyKey(columns);
if (PropertiesCache.TryGetValue(propKey, out var propValue))
return propValue;

var properties = new List<ReaderProperty>(columns.Length);
var properties = new ReaderProperty[columns.Length];
for (var i = 0; i < columns.Length; i++)
{
PropertyInfo prop;
var propAttributeSource = sourceType.GetPropertyByName(columns[i].Replace("_", ""));
var propSource = sourceType.GetPropertyByName(props[i].Name.Replace("_", ""));

if (propSource.IsNull() && propAttributeSource.IsNull())
continue;
else
prop = propSource.IsNull() ? propAttributeSource : propSource;

var setter = (Action<object, object>)ExpressionBuildHelper.BuildPropertySetter(prop);

properties.Add(new ReaderProperty { Idx = i, Setter = setter, Name = prop.Name });
var property = sourcePropertyInfo.FirstOrDefault(x => x.AttributeName == columns[i].Replace("_", "")
&& x.IsInResponse.IsTrue());
if (property.IsNotNull())
{
var setter = (Action<object, object>)ExpressionBuildHelper.BuildPropertySetter(property!.Property);

properties[i] = new ReaderProperty { Idx = i, Setter = setter, Name = property.SourceName };
}
}

var propertiesArray = properties.ToArray();
PropertiesCache[propKey] = propertiesArray;
PropertiesCache[propKey] = properties;

return propertiesArray;
return properties;
}
}
}
6 changes: 3 additions & 3 deletions src/shared/GeneralAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@
[assembly: AssemblyMetadata("ContactName", "RzR")]
[assembly: AssemblyMetadata("ContactEmail", "ddpRzR@hotmail.com")]
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.1.8361")]
[assembly: AssemblyFileVersion("1.0.1.8361")]
[assembly: AssemblyInformationalVersion("1.0.1.8361")]
Loading