Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grouping, string filters case insensitive, filters for date and more #33

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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 Kendo.DynamicLinq.Tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void DataContractJsonSerializerSerializesAggregates()
serializer.WriteObject(stream, people.AsQueryable().ToDataSourceResult(1, 2, null, null, new [] { new Aggregator {
Aggregate = "sum",
Field = "Age"
} }));
} },null));

var json = Encoding.UTF8.GetString(stream.ToArray()).Replace("\"__type\":\"DynamicClass2:#\",", "");

Expand Down
12 changes: 11 additions & 1 deletion Kendo.DynamicLinq/DataSourceRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ public class DataSourceRequest
/// <summary>
/// Specifies the requested sort order.
/// </summary>
public IEnumerable<Sort> Sort { get; set; }
public IEnumerable<Sort> Sort { get; set; }

/// <summary>
/// Specifies the requested grouping.
/// </summary>
public IEnumerable<Group> Group { get; set; }

/// <summary>
/// Specifies the requested aggregators.
/// </summary>
public IEnumerable<Aggregator> Aggregate { get; set; }

/// <summary>
/// Specifies the requested filter.
Expand Down
20 changes: 12 additions & 8 deletions Kendo.DynamicLinq/DataSourceResult.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;

namespace Kendo.DynamicLinq
{
/// <summary>
/// Describes the result of Kendo DataSource read operation.
/// Describes the result of Kendo DataSource read operation.
/// </summary>
[KnownType("GetKnownTypes")]
public class DataSourceResult
{
/// <summary>
/// Represents a single page of processed data.
/// Represents a single page of processed data.
/// </summary>
public IEnumerable Data { get; set; }

/// <summary>
/// The total number of records available.
/// Represents a single page of processed grouped data.
/// </summary>
public IEnumerable Group { get; set; }

/// <summary>
/// The total number of records available.
/// </summary>
public int Total { get; set; }

/// <summary>
/// Represents a requested aggregates.
/// Represents a requested aggregates.
/// </summary>
public object Aggregates { get; set; }

/// <summary>
/// Used by the KnownType attribute which is required for WCF serialization support
/// Used by the KnownType attribute which is required for WCF serialization support
/// </summary>
/// <returns></returns>
private static Type[] GetKnownTypes()
Expand All @@ -47,4 +51,4 @@ private static Type[] GetKnownTypes()
.ToArray();
}
}
}
}
90 changes: 90 additions & 0 deletions Kendo.DynamicLinq/EnumerableExtenstions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;

namespace Kendo.DynamicLinq
{
public static class EnumerableExtenstions
{
public static dynamic GroupByMany<TElement>(this IEnumerable<TElement> elements,
IEnumerable<Group> groupSelectors)
{
//create a new list of Kendo Group Selectors
var selectors = new List<GroupSelector<TElement>>(groupSelectors.Count());
foreach (var selector in groupSelectors)
{
//compile the Dynamic Expression Lambda for each one
var expression =
DynamicExpression.ParseLambda(typeof(TElement), typeof(object), selector.Field);
//add it to the list
selectors.Add(new GroupSelector<TElement>
{
Selector = (Func<TElement, object>) expression.Compile(),
Field = selector.Field,
Aggregates = selector.Aggregates
});
}
//call the actual group by method
return elements.GroupByMany(selectors.ToArray());
}
//returned value should look like the following
// [{
// aggregates: {
// FIEL1DNAME: {
// FUNCTON1NAME: FUNCTION1VALUE,
// FUNCTON2NAME: FUNCTION2VALUE
// },
// FIELD2NAME: {
// FUNCTON1NAME: FUNCTION1VALUE
// }
// },
// field: FIELDNAME, // the field by which the data items are grouped
// hasSubgroups: true, // true if there are subgroups
// items: [
// // either the subgroups or the data items
// {
// aggregates: {
// //nested group aggregates
// },
// field: NESTEDGROUPFIELDNAME,
// hasSubgroups: false,
// items: [
// // data records
// ],
// value: NESTEDGROUPVALUE
// },
// //nestedgroup2, nestedgroup3, etc.
// ],
// value: VALUE // the group key
//} /* other groups */
//]
//for more info check http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-schema.groups

public static dynamic GroupByMany<TElement>(this IEnumerable<TElement> elements,
params GroupSelector<TElement>[] groupSelectors)
{
if (groupSelectors.Length > 0)
{
//get selector
var selector = groupSelectors.First();
var nextSelectors = groupSelectors.Skip(1).ToArray(); //reduce the list recursively until zero
return
//group by and return
elements.GroupBy(selector.Selector).Select(
g => new GroupResult
{
Value = g.Key,
Aggregates = selector.Aggregates,
HasSubgroups = groupSelectors.Length > 1,
Count = g.Count(),
//recursivly group the next selectors
Items = g.GroupByMany(nextSelectors),
SelectorField = selector.Field
});
}
//if there are not more group selectors return data
return elements;
}
}
}
11 changes: 11 additions & 0 deletions Kendo.DynamicLinq/Group.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Kendo.DynamicLinq
{
public class Group : Sort
{
[DataMember(Name = "aggregates")]
public IEnumerable<Aggregator> Aggregates { get; set; }
}
}
36 changes: 36 additions & 0 deletions Kendo.DynamicLinq/GroupResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Kendo.DynamicLinq
{
[DataContract(Name = "groupresult")]
public class GroupResult
{
//small letter properties are kendo js properties so please execuse the warnings
//for more info check http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-schema.groups
[DataMember(Name = "value")]
public object Value { get; set; }

public string SelectorField { get; set; }
[DataMember(Name = "field")]
public string Field
{
get { return string.Format("{0} ({1})", this.SelectorField, this.Count); }
}
public int Count { get; set; }

[DataMember(Name = "aggregates")]
public IEnumerable<Aggregator> Aggregates { get; set; }

[DataMember(Name = "items")]
public dynamic Items { get; set; }

[DataMember(Name = "hasSubgroups")]
public bool HasSubgroups { get; set; } // true if there are subgroups

public override string ToString()
{
return string.Format("{0} ({1})", this.Value, this.Count);
}
}
}
13 changes: 13 additions & 0 deletions Kendo.DynamicLinq/GroupSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;

namespace Kendo.DynamicLinq
{
public class GroupSelector<TElement>
{
public Func<TElement, object> Selector { get; set; }
public string Field { get; set; }
public IEnumerable<Aggregator> Aggregates { get; set; }

}
}
119 changes: 62 additions & 57 deletions Kendo.DynamicLinq/Kendo.DynamicLinq.csproj
Original file line number Diff line number Diff line change
@@ -1,64 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2BD75D53-E0EA-4995-8B0F-60AD709945AC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Kendo.DynamicLinq</RootNamespace>
<AssemblyName>Kendo.DynamicLinq</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Linq.Dynamic">
<HintPath>..\packages\System.Linq.Dynamic.1.0.0\lib\net40\System.Linq.Dynamic.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
<ItemGroup>
<Compile Include="Aggregate.cs" />
<Compile Include="DataSourceRequest.cs" />
<Compile Include="DataSourceResult.cs" />
<Compile Include="Filter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryableExtensions.cs" />
<Compile Include="Sort.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Kendo.DynamicLinq.nuspec" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2BD75D53-E0EA-4995-8B0F-60AD709945AC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Kendo.DynamicLinq</RootNamespace>
<AssemblyName>Kendo.DynamicLinq</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Linq.Dynamic, Version=1.0.6132.35681, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\System.Linq.Dynamic.1.0.7\lib\net40\System.Linq.Dynamic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
<ItemGroup>
<Compile Include="Aggregate.cs" />
<Compile Include="DataSourceRequest.cs" />
<Compile Include="DataSourceResult.cs" />
<Compile Include="EnumerableExtenstions.cs" />
<Compile Include="Filter.cs" />
<Compile Include="Group.cs" />
<Compile Include="GroupResult.cs" />
<Compile Include="GroupSelector.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryableExtensions.cs" />
<Compile Include="Sort.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Kendo.DynamicLinq.nuspec" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>
Loading