Skip to content
Merged

save #380

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
21 changes: 21 additions & 0 deletions System.Linq.Dynamic.Core.sln
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docfx", "docfx", "{012536E6
docfx\toc.yml = docfx\toc.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lab", "lab", "{E97833C1-77B6-44E2-8793-C1F952CA936F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Z.Dynamic.Core.Lab", "Z.Dynamic.Core.Lab\Z.Dynamic.Core.Lab.csproj", "{CDD8D5BF-A212-43DD-B043-4B7242C553E0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -504,6 +508,22 @@ Global
{CD80A3AC-B0E1-45ED-BE07-DE6A0F1D4CD8}.Release|x64.Build.0 = Release|Any CPU
{CD80A3AC-B0E1-45ED-BE07-DE6A0F1D4CD8}.Release|x86.ActiveCfg = Release|Any CPU
{CD80A3AC-B0E1-45ED-BE07-DE6A0F1D4CD8}.Release|x86.Build.0 = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|ARM.Build.0 = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|x64.ActiveCfg = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|x64.Build.0 = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|x86.ActiveCfg = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Debug|x86.Build.0 = Debug|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|Any CPU.Build.0 = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|ARM.ActiveCfg = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|ARM.Build.0 = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|x64.ActiveCfg = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|x64.Build.0 = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|x86.ActiveCfg = Release|Any CPU
{CDD8D5BF-A212-43DD-B043-4B7242C553E0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -534,6 +554,7 @@ Global
{D160E2CF-A7E1-4DDE-9AB8-8CFB0087DCEB} = {7971CAEB-B9F2-416B-966D-2D697C4C1E62}
{0034821E-740D-4553-821B-14CE9213C43C} = {7971CAEB-B9F2-416B-966D-2D697C4C1E62}
{CD80A3AC-B0E1-45ED-BE07-DE6A0F1D4CD8} = {122BC4FA-7563-4E35-9D17-077F16F1629F}
{CDD8D5BF-A212-43DD-B043-4B7242C553E0} = {E97833C1-77B6-44E2-8793-C1F952CA936F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {94C56722-194E-4B8B-BC23-B3F754E89A20}
Expand Down
12 changes: 12 additions & 0 deletions Z.Dynamic.Core.Lab/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace Z.Dynamic.Core.Lab
{
class Program
{
static void Main(string[] args)
{
Request_OrderBy_StringComparer.Execute();
}
}
}
42 changes: 42 additions & 0 deletions Z.Dynamic.Core.Lab/Request_OrderBy_StringComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;

namespace Z.Dynamic.Core.Lab
{
class Request_OrderBy_StringComparer
{
public class Customer
{
public string City { get; set; }
public List<Order> Orders { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }
}
public class Order
{
}

public static void Execute()
{
List<Customer> customers = new List<Customer>() { new Customer() { CompanyName = "Ååå"} ,
new Customer() { CompanyName = "Bbb" } ,
new Customer() { CompanyName = "Ååå" } ,
new Customer() { CompanyName = "Bbb" } ,
new Customer() { CompanyName = "Aaa" },
new Customer() { CompanyName = "Aaa" },
};

CultureInfo culture = new CultureInfo("nb-NO");
var test1 = customers.AsQueryable().OrderBy(x => x.CompanyName, StringComparer.Create(culture, true)).ToList();
var test2 = customers.AsQueryable().OrderBy(x => x.CompanyName).ToList();
var test3 = customers.AsQueryable()
.OrderBy("City").ThenBy("CompanyName", StringComparer.Create(culture, true)).ToDynamicList();
var test4 = customers.AsQueryable()
.OrderBy("CompanyName", StringComparer.Create(culture, true)).ToDynamicList();
}
}
}
32 changes: 32 additions & 0 deletions Z.Dynamic.Core.Lab/Template_Simple.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Dynamic.Core;

namespace Z.Dynamic.Core.Lab
{
public class Template_Simple
{
public class Customer
{
public string City { get; set; }
public List<Order> Orders { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }
}
public class Order
{
}

public static void Execute()
{
List<Customer> customers = new List<Customer>() {new Customer() {City = "ZZZ", CompanyName = "ZZZ", Orders = new List<Order>() {new Order()}, Phone = "555 5555"}};

var query = customers.AsQueryable()
.Where("City == @0 and Orders.Count >= @1", "ZZZ", 1)
.OrderBy("CompanyName")
.Select("new(CompanyName as Name, Phone)").ToDynamicList();
}
}
}
16 changes: 16 additions & 0 deletions Z.Dynamic.Core.Lab/Z.Dynamic.Core.Lab.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\System.Linq.Dynamic.Core\System.Linq.Dynamic.Core.csproj" />
</ItemGroup>

</Project>
108 changes: 100 additions & 8 deletions src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,35 @@ public static IOrderedQueryable<TSource> OrderBy<TSource>([NotNull] this IQuerya
return OrderBy(source, ParsingConfig.Default, ordering, args);
}

/// <summary>
/// Sorts the elements of a sequence in ascending or descending order according to a key.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence of values to order.</param>
/// <param name="config">The <see cref="ParsingConfig"/>.</param>
/// <param name="ordering">An expression string to indicate values to order by.</param>
/// <param name="comparer">The comparer to use to order by.</param>
/// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
/// <returns>A <see cref="IQueryable{T}"/> whose elements are sorted according to the specified <paramref name="ordering"/>.</returns>
public static IOrderedQueryable<TSource> OrderBy<TSource>([NotNull] this IQueryable<TSource> source, [NotNull] ParsingConfig config, [NotNull] string ordering, IComparer comparer, params object[] args)
{
return (IOrderedQueryable<TSource>)InternalOrderBy((IQueryable)source, config, ordering, comparer, args);
}

/// <summary>
/// Sorts the elements of a sequence in ascending or descending order according to a key.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence of values to order.</param>
/// <param name="ordering">An expression string to indicate values to order by.</param>
/// <param name="comparer">The comparer to use to order by.</param>
/// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
/// <returns>A <see cref="IQueryable{T}"/> whose elements are sorted according to the specified <paramref name="ordering"/>.</returns>
public static IOrderedQueryable<TSource> OrderBy<TSource>([NotNull] this IQueryable<TSource> source, [NotNull] string ordering, IComparer comparer, params object[] args)
{
return OrderBy(source, ParsingConfig.Default, ordering, comparer, args);
}

/// <summary>
/// Sorts the elements of a sequence in ascending or descending order according to a key.
/// </summary>
Expand All @@ -1289,6 +1318,11 @@ public static IOrderedQueryable<TSource> OrderBy<TSource>([NotNull] this IQuerya
/// </code>
/// </example>
public static IOrderedQueryable OrderBy([NotNull] this IQueryable source, [NotNull] ParsingConfig config, [NotNull] string ordering, params object[] args)
{
return InternalOrderBy(source, config, ordering, null, args);
}

internal static IOrderedQueryable InternalOrderBy([NotNull] IQueryable source, [NotNull] ParsingConfig config, [NotNull] string ordering, IComparer comparer, params object[] args)
{
Check.NotNull(source, nameof(source));
Check.NotNull(config, nameof(config));
Expand All @@ -1302,10 +1336,22 @@ public static IOrderedQueryable OrderBy([NotNull] this IQueryable source, [NotNu

foreach (DynamicOrdering dynamicOrdering in dynamicOrderings)
{
queryExpr = Expression.Call(
typeof(Queryable), dynamicOrdering.MethodName,
new[] { source.ElementType, dynamicOrdering.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)));
if (comparer == null)
{
queryExpr = Expression.Call(
typeof(Queryable), dynamicOrdering.MethodName,
new[] { source.ElementType, dynamicOrdering.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)));
}
else
{
var comparerGenericType = typeof(IComparer<>).MakeGenericType(dynamicOrdering.Selector.Type);
queryExpr = Expression.Call(
typeof(Queryable), dynamicOrdering.MethodName,
new[] { source.ElementType, dynamicOrdering.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)),
Expression.Constant(comparer, comparerGenericType));
}
}

var optimized = OptimizeExpression(queryExpr);
Expand Down Expand Up @@ -2176,6 +2222,35 @@ public static IOrderedQueryable<TSource> ThenBy<TSource>([NotNull] this IOrdered
{
return ThenBy(source, ParsingConfig.Default, ordering, args);
}

/// <summary>
/// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence of values to order.</param>
/// <param name="config">The <see cref="ParsingConfig"/>.</param>
/// <param name="ordering">An expression string to indicate values to order by.</param>
/// <param name="comparer">The comparer to use to order by.</param>
/// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
/// <returns>A <see cref="IOrderedQueryable{T}"/> whose elements are sorted according to the specified <paramref name="ordering"/>.</returns>
public static IOrderedQueryable<TSource> ThenBy<TSource>([NotNull] this IOrderedQueryable<TSource> source, [NotNull] ParsingConfig config, [NotNull] string ordering, IComparer comparer, params object[] args)
{
return (IOrderedQueryable<TSource>)InternalThenBy((IOrderedQueryable)source, config, ordering, comparer, args);
}

/// <summary>
/// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence of values to order.</param>
/// <param name="ordering">An expression string to indicate values to order by.</param>
/// <param name="comparer">The comparer to use to order by.</param>
/// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
/// <returns>A <see cref="IOrderedQueryable{T}"/> whose elements are sorted according to the specified <paramref name="ordering"/>.</returns>
public static IOrderedQueryable<TSource> ThenBy<TSource>([NotNull] this IOrderedQueryable<TSource> source, [NotNull] string ordering, IComparer comparer, params object[] args)
{
return ThenBy(source, ParsingConfig.Default, ordering, comparer, args);
}
/// <summary>
/// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
/// </summary>
Expand All @@ -2193,6 +2268,11 @@ public static IOrderedQueryable<TSource> ThenBy<TSource>([NotNull] this IOrdered
/// </code>
/// </example>
public static IOrderedQueryable ThenBy([NotNull] this IOrderedQueryable source, [NotNull] ParsingConfig config, [NotNull] string ordering, params object[] args)
{
return InternalThenBy(source, config, ordering, null, args);
}

internal static IOrderedQueryable InternalThenBy([NotNull] this IOrderedQueryable source, [NotNull] ParsingConfig config, [NotNull] string ordering, IComparer comparer, params object[] args)
{
Check.NotNull(source, nameof(source));
Check.NotNull(config, nameof(config));
Expand All @@ -2206,10 +2286,22 @@ public static IOrderedQueryable ThenBy([NotNull] this IOrderedQueryable source,

foreach (DynamicOrdering dynamicOrdering in dynamicOrderings)
{
queryExpr = Expression.Call(
typeof(Queryable), dynamicOrdering.MethodName,
new[] { source.ElementType, dynamicOrdering.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)));
if (comparer == null)
{
queryExpr = Expression.Call(
typeof(Queryable), dynamicOrdering.MethodName,
new[] { source.ElementType, dynamicOrdering.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)));
}
else
{
var comparerGenericType = typeof(IComparer<>).MakeGenericType(dynamicOrdering.Selector.Type);
queryExpr = Expression.Call(
typeof(Queryable), dynamicOrdering.MethodName,
new[] { source.ElementType, dynamicOrdering.Selector.Type },
queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)),
Expression.Constant(comparer, comparerGenericType));
}
}

var optimized = OptimizeExpression(queryExpr);
Expand Down