Skip to content

Commit

Permalink
Adjust dynamic property/ies select avoid System.Linq.Dynamic.Core
Browse files Browse the repository at this point in the history
Adjust and rebuild dynamic propert select and dynamic result avoiding package reference.
  • Loading branch information
I-RzR-I committed Jan 9, 2025
1 parent 4067f4f commit ec39a31
Show file tree
Hide file tree
Showing 14 changed files with 1,597 additions and 23 deletions.
124 changes: 109 additions & 15 deletions src/DomainCommonExtensions/ArraysExtensions/DynamicListExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@

using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using DomainCommonExtensions.CommonExtensions;
using DomainCommonExtensions.Helpers.Internal.AnonymousSelect;

#region OLD Using System.Linq.Dynamic.Core
//using System.Linq.Dynamic.Core;
//using System.Linq.Dynamic.Core.Parser;
#endregion

#endregion

Expand All @@ -32,8 +37,57 @@ namespace DomainCommonExtensions.ArraysExtensions
/// <remarks></remarks>
public static class DynamicListExtensions
{
#region OLD Using System.Linq.Dynamic.Core

/*
// Using System.Linq.Dynamic.Core
// // <summary>
// // Parse input data (List) to dynamic result (list)
// // </summary>
// // <param name="input">List of T input data</param>
// // <param name="fields">Required fields</param>
// // <returns></returns>
// // <typeparam name="T"></typeparam>
// // <remarks></remarks>
// public static IList<dynamic> ParseListOfTInDynamic<T>(this List<T> input, IEnumerable<string> fields = null)
// {
// var data = input.AsQueryable();
// var requiredFields = typeof(T).GetSelectedFieldFromEntity(fields);
//
// var result = data.Select("new {" + requiredFields + "}").ToDynamicList();
//
// return result;
// }
*/

/*
// Using System.Linq.Dynamic.Core
// /// <summary>
// /// Parse input data (IEnumerable) to dynamic result (list)
// /// </summary>
// /// <param name="input">IEnumerable of T input data</param>
// /// <param name="fields">Required fields</param>
// /// <returns></returns>
// /// <typeparam name="T"></typeparam>
// /// <remarks></remarks>
// public static IList<dynamic> ParseEnumerableOfTInDynamic<T>(this IEnumerable<T> input,
// IEnumerable<string> fields = null)
// {
// var data = input.AsQueryable();
// var requiredFields = typeof(T).GetSelectedFieldFromEntity(fields);
// var result = data.Select("new {" + requiredFields + "}").ToDynamicList();
// return result;
// }
*/

#endregion

/// <summary>
/// Parse input data (List) to dynamic result (list)
/// Parse input data (IEnumerable) to dynamic result (list)
/// </summary>
/// <param name="input">List of T input data</param>
/// <param name="fields">Required fields</param>
Expand All @@ -44,29 +98,45 @@ public static IList<dynamic> ParseListOfTInDynamic<T>(this List<T> input, IEnume
{
var data = input.AsQueryable();
var requiredFields = typeof(T).GetSelectedFieldFromEntity(fields);
var parameter = Expression.Parameter(data.ElementType, "x");
var lambdaExpression = ExpressionHelper.ParseLambda(parameter, data.ElementType, false, requiredFields.Split(','));

var selectCall = Expression.Call(
typeof(Queryable),
"Select",
new[] { parameter.Type, lambdaExpression.Body.Type/*source.ElementType*/ },
data.Expression,
Expression.Quote(lambdaExpression));

var result = data.Select("new {" + requiredFields + "}").ToDynamicList();
var result = data.Provider.CreateQuery(selectCall);

return result;
return result.Cast<dynamic>().ToList();
}

/// <summary>
/// Parse input data (IEnumerable) to dynamic result (list)
/// Parse input data (List) to dynamic result (list)
/// </summary>
/// <param name="input">IEnumerable of T input data</param>
/// <param name="fields">Required fields</param>
/// <returns></returns>
/// <typeparam name="T"></typeparam>
/// <remarks></remarks>
public static IList<dynamic> ParseEnumerableOfTInDynamic<T>(this IEnumerable<T> input,
IEnumerable<string> fields = null)
public static IList<dynamic> ParseEnumerableOfTInDynamic<T>(this IEnumerable<T> input, IEnumerable<string> fields = null)
{
var data = input.AsQueryable();
var requiredFields = typeof(T).GetSelectedFieldFromEntity(fields);
var parameter = Expression.Parameter(data.ElementType, "x");
var lambdaExpression = ExpressionHelper.ParseLambda(parameter, data.ElementType, false, requiredFields.Split(','));

var result = data.Select("new {" + requiredFields + "}").ToDynamicList();
var selectCall = Expression.Call(
typeof(Queryable),
"Select",
new[] { parameter.Type, lambdaExpression.Body.Type/*source.ElementType*/ },
data.Expression,
Expression.Quote(lambdaExpression));

var result = data.Provider.CreateQuery(selectCall);

return result;
return result.Cast<dynamic>().ToList();
}

/// <summary>
Expand All @@ -79,12 +149,36 @@ public static IList<dynamic> ParseEnumerableOfTInDynamic<T>(this IEnumerable<T>
public static IQueryable SelectProperty(this IQueryable source, string prop)
{
var parameter = Expression.Parameter(source.ElementType, "x");
var property = prop.Split(',')
.Aggregate((Expression)parameter, Expression.Property);
var selector = Expression.Lambda(property, parameter);
var propEx = Expression.Property(parameter, prop);
var selector = Expression.Lambda(propEx, parameter);
var selectCall = Expression.Call(
typeof(Queryable),
"Select",
new[] { parameter.Type, propEx.Type },
source.Expression,
Expression.Quote(selector));

return source.Provider.CreateQuery(selectCall);
}

/// <summary>
/// Generate select multiple properties
/// </summary>
/// <param name="source">Data source IQueryable</param>
/// <param name="props">Properties name</param>
/// <returns></returns>
/// <remarks></remarks>
public static IQueryable SelectMultipleProperties(this IQueryable source, params string[] props)
{
var parameter = Expression.Parameter(source.ElementType, "x");
var lambdaExpression = ExpressionHelper.ParseLambda(parameter, source.ElementType, true, props);

var selectCall = Expression.Call(
typeof(Queryable), "Select", new[] { parameter.Type, property.Type },
source.Expression, Expression.Quote(selector));
typeof(Queryable),
"Select",
new[] { parameter.Type, lambdaExpression.Body.Type/*source.ElementType*/ },
source.Expression,
Expression.Quote(lambdaExpression));

return source.Provider.CreateQuery(selectCall);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static void CopyProperties(this object source, object destination)
var targetProperty = typeDest.GetProperty(srcProp.Name);
if (targetProperty.IsNull())
continue;
if (!targetProperty.CanWrite)
if (!targetProperty!.CanWrite)
continue;
if (targetProperty.GetSetMethod(true) != null && targetProperty.GetSetMethod(true).IsPrivate)
continue;
Expand Down
106 changes: 106 additions & 0 deletions src/DomainCommonExtensions/CommonExtensions/TypeBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// ***********************************************************************
// Assembly : RzR.Shared.Extensions.DomainCommonExtensions
// Author : RzR
// Created On : 2025-01-08 09:27
//
// Last Modified By : RzR
// Last Modified On : 2025-01-08 09:28
// ***********************************************************************
// <copyright file="TypeBuilderExtensions.cs" company="RzR SOFT & TECH">
// Copyright © RzR. All rights reserved.
// </copyright>
//
// <summary>
// </summary>
// ***********************************************************************

#region U S A G E S

// ReSharper disable RedundantUsingDirective

using System;
using System.Reflection;
using System.Reflection.Emit;

#endregion

namespace DomainCommonExtensions.CommonExtensions
{
/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A type builder extensions.
/// </summary>
/// =================================================================================================
public static class TypeBuilderExtensions
{

#if !(NET35 || NET40 || SILVERLIGHT || WPSL || UAP10_0)

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// Creates a System.Type object for the class. After defining fields and methods
/// on the class, CreateType is called in order to load its Type object.
/// </summary>
/// <param name="tb">The TypeBuilder to act on.</param>
/// <returns>
/// Returns the new System.Type object for this class.
/// </returns>
/// =================================================================================================
public static Type CreateType(this TypeBuilder tb)
{
return tb.CreateTypeInfo().AsType();
}
#endif

#if NET35 || NET40 || SILVERLIGHT || WPSL || NETCOREAPP || NETSTANDARD2_1

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A TypeBuilder extension method that define property.
/// </summary>
/// <param name="tb">The TypeBuilder to act on.</param>
/// <param name="name">The name.</param>
/// <param name="attributes">The attributes.</param>
/// <param name="callingConvention">The calling convention.</param>
/// <param name="returnType">Type of the return.</param>
/// <param name="parameterTypes">List of types of the parameters.</param>
/// <returns>
/// A PropertyBuilder.
/// </returns>
/// =================================================================================================
public static PropertyBuilder DefineProperty(this TypeBuilder tb, string name, PropertyAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
{
return tb.DefineProperty(name, attributes, returnType, parameterTypes);
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A TypeBuilder extension method that converts a builder to a type.
/// </summary>
/// <param name="builder">The builder to act on.</param>
/// <returns>
/// A Type.
/// </returns>
/// =================================================================================================
public static Type AsType(this TypeBuilder builder)
{
return builder;
}

/// -------------------------------------------------------------------------------------------------
/// <summary>
/// A GenericTypeParameterBuilder extension method that converts a builder to a type.
/// </summary>
/// <param name="builder">The builder to act on.</param>
/// <returns>
/// A Type.
/// </returns>
/// =================================================================================================
public static Type AsType(this GenericTypeParameterBuilder builder)
{
return builder;
}
#endif
}
}
15 changes: 15 additions & 0 deletions src/DomainCommonExtensions/DataTypeExtensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1574,5 +1574,20 @@ public static bool IsValidJsonArray(this string source)
}

#endif

/// <summary>
/// Escape backslash from source string
/// </summary>
/// <param name="source">Source string</param>
/// <param name="customCharEscape">Custom char to be escaped in source. Default value is '|'.</param>
/// <returns></returns>
/// <remarks>Replace by default '\' => '\\', and custom char(string value) from 'x' => '\x'</remarks>
public static string EscapeBackSlash(this string source, string customCharEscape = "|")
{
source = source.Replace(@"\", @"\\");
source = source.Replace(customCharEscape, @$"\{customCharEscape}");

return source;
}
}
}
20 changes: 18 additions & 2 deletions src/DomainCommonExtensions/DomainCommonExtensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CodeSource" Version="1.0.6.933" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.3" />
<PackageReference Include="CodeSource" Version="2.0.0" />
<!--<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.3" />-->
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == 'netstandard2.1'">
Expand All @@ -66,6 +66,10 @@
</PackageReference>
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
</ItemGroup>

Expand All @@ -74,6 +78,18 @@
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.CodeAnalysis.Common">
<Version>4.2.0</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="Microsoft.CodeAnalysis.Common">
<Version>4.2.0</Version>
</PackageReference>
</ItemGroup>

<ProjectExtensions>
<VisualStudio>
<UserProperties BuildVersion_StartDate="2022/8/22" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ArrayList Collection
{
var arg = arrayList;
if (enumerator.Current.IsNull()) continue;
var dictionaryEntry = (DictionaryEntry)enumerator.Current;
var dictionaryEntry = (DictionaryEntry)enumerator.Current!;
arg.Add(dictionaryEntry.Value);
}

Expand Down
Loading

0 comments on commit ec39a31

Please sign in to comment.