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
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>9.0.1</Version>
<Version>9.0.2-beta01</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
47 changes: 39 additions & 8 deletions src/BootstrapBlazor/Extensions/LambdaExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,24 @@ private static IEnumerable<TItem> EnumerableOrderBy<TItem>(IEnumerable<TItem> qu

IEnumerable<TItem> EnumerableOrderBySimple()
{
var type = typeof(TItem);
IEnumerable<TItem>? ret = null;
var pi = typeof(TItem).GetPropertyByName(propertyName);
if (pi != null)
if (type.IsInterface && type == typeof(IDynamicObject))
{
var methodName = sortOrder == SortOrder.Desc ? nameof(OrderByDescendingInternal) : nameof(OrderByInternal);
ret = query.AsQueryable().InvokeSortByPropertyInfo(methodName, pi);
var instance = query.FirstOrDefault();
if (instance != null)
{
ret = CastAndOrder(query, instance.GetType(), propertyName, sortOrder);
}
}
else
{
var pi = type.GetPropertyByName(propertyName);
if (pi != null)
{
var methodName = sortOrder == SortOrder.Desc ? nameof(OrderByDescendingInternal) : nameof(OrderByInternal);
ret = query.AsQueryable().InvokeSortByPropertyInfo(methodName, pi);
}
}
return ret ?? query;
}
Expand All @@ -476,6 +488,25 @@ IEnumerable<TItem> EnumerableOrderByComplex()
}
}

private static IEnumerable<TItem>? CastAndOrder<TItem>(IEnumerable<TItem> query, Type propertyType, string propertyName, SortOrder sortOrder)
{
IEnumerable<TItem>? ret = null;
var castMethod = typeof(Enumerable).GetMethod(nameof(Enumerable.Cast), BindingFlags.Static | BindingFlags.Public);
if (castMethod != null)
{
var mi = castMethod.MakeGenericMethod(propertyType);
var collection = mi.Invoke(null, [query]);

var orderMethod = typeof(LambdaExtensions).GetMethod(nameof(EnumerableOrderBy), BindingFlags.Static | BindingFlags.NonPublic);
if (orderMethod != null)
{
var miOrder = orderMethod.MakeGenericMethod(propertyType);
ret = miOrder.Invoke(null, [collection, propertyName, sortOrder]) as IEnumerable<TItem>;
}
}
return ret;
}

private static IEnumerable<TItem> EnumerableThenBy<TItem>(IEnumerable<TItem> query, string propertyName, SortOrder sortOrder)
{
return propertyName.Contains('.') ? EnumerableThenByComplex() : EnumerableThenBySimple();
Expand Down Expand Up @@ -583,13 +614,13 @@ IQueryable<TItem> QueryableThenByComplex()

private static IOrderedQueryable<TItem> ThenByDescendingInternalByName<TItem, TKey>(IOrderedQueryable<TItem> query, string propertyName) => query.ThenByDescending(GetPropertyLambdaByName<TItem, TKey>(propertyName));

private static IOrderedQueryable<TItem> OrderByInternal<TItem, TKey>(IQueryable<TItem> query, System.Reflection.PropertyInfo memberProperty) => query.OrderBy(GetPropertyLambda<TItem, TKey>(memberProperty));
private static IOrderedQueryable<TItem> OrderByInternal<TItem, TKey>(IQueryable<TItem> query, PropertyInfo memberProperty) => query.OrderBy(GetPropertyLambda<TItem, TKey>(memberProperty));

private static IOrderedQueryable<TItem> OrderByDescendingInternal<TItem, TKey>(IQueryable<TItem> query, System.Reflection.PropertyInfo memberProperty) => query.OrderByDescending(GetPropertyLambda<TItem, TKey>(memberProperty));
private static IOrderedQueryable<TItem> OrderByDescendingInternal<TItem, TKey>(IQueryable<TItem> query, PropertyInfo memberProperty) => query.OrderByDescending(GetPropertyLambda<TItem, TKey>(memberProperty));

private static IOrderedQueryable<TItem> ThenByInternal<TItem, TKey>(IOrderedQueryable<TItem> query, System.Reflection.PropertyInfo memberProperty) => query.ThenBy(GetPropertyLambda<TItem, TKey>(memberProperty));
private static IOrderedQueryable<TItem> ThenByInternal<TItem, TKey>(IOrderedQueryable<TItem> query, PropertyInfo memberProperty) => query.ThenBy(GetPropertyLambda<TItem, TKey>(memberProperty));

private static IOrderedQueryable<TItem> ThenByDescendingInternal<TItem, TKey>(IOrderedQueryable<TItem> query, System.Reflection.PropertyInfo memberProperty) => query.ThenByDescending(GetPropertyLambda<TItem, TKey>(memberProperty));
private static IOrderedQueryable<TItem> ThenByDescendingInternal<TItem, TKey>(IOrderedQueryable<TItem> query, PropertyInfo memberProperty) => query.ThenByDescending(GetPropertyLambda<TItem, TKey>(memberProperty));

private static Expression<Func<TItem, TKey>> GetPropertyLambda<TItem, TKey>(PropertyInfo pi)
{
Expand Down
57 changes: 57 additions & 0 deletions test/UnitTest/Extensions/LambadaExtensionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone

using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Dynamic;
using System.Linq.Expressions;

Expand Down Expand Up @@ -416,6 +417,62 @@ public void Sort_Queryable_Complex()
Assert.Equal(10, orderFoos.ElementAt(0).Foo!.Count);
}

[Fact]
public void Sort_IDynamicObject_Ok()
{
var dataTable = new DataTable();

DataColumn column = new DataColumn
{
DataType = Type.GetType("System.Int32"),
ColumnName = "ID"
};
dataTable.Columns.Add(column);

column = new DataColumn
{
DataType = Type.GetType("System.String"),
ColumnName = "Name"
};
dataTable.Columns.Add(column);

//Creating some rows
DataRow row = dataTable.NewRow();
row["ID"] = 1;
row["Name"] = "Bob";
dataTable.Rows.Add(row);

row = dataTable.NewRow();
row["ID"] = 3;
row["Name"] = "Adam";
dataTable.Rows.Add(row);

row = dataTable.NewRow();
row["ID"] = 2;
row["Name"] = "Jane";
dataTable.Rows.Add(row);

var context = new DataTableDynamicContext(dataTable, (context, col) => { });
var items = context.GetItems().ToList();

// 未排序
Assert.Equal("Bob", items[0].GetValue("Name"));
Assert.Equal("Adam", items[1].GetValue("Name"));
Assert.Equal("Jane", items[2].GetValue("Name"));

// Name 排序
var nameItems = items.Sort("Name", SortOrder.Asc).ToList();
Assert.Equal("Adam", nameItems[0].GetValue("Name"));
Assert.Equal("Bob", nameItems[1].GetValue("Name"));
Assert.Equal("Jane", nameItems[2].GetValue("Name"));

// Name 倒序
nameItems = items.Sort("Name", SortOrder.Desc).ToList();
Assert.Equal("Adam", nameItems[2].GetValue("Name"));
Assert.Equal("Bob", nameItems[1].GetValue("Name"));
Assert.Equal("Jane", nameItems[0].GetValue("Name"));
}

[Fact]
public void GetPropertyValueLambda_Null()
{
Expand Down