added support for lots of new aggregate helpers.

first breaking change but I think people will be okay with it :)
This commit is contained in:
David Lebee 2018-10-25 21:01:44 -05:00
parent dcaf114a09
commit 695d3085d1
5 changed files with 84 additions and 29 deletions

View File

@ -47,7 +47,16 @@ namespace PoweredSoft.DynamicLinq.Test
{
Id = t.Id,
FirstNames = t.Bs.SelectMany(t2 => t2.FirstNames).ToList(),
FirstNamesLists = t.Bs.Select(t2 => t2.FirstNames).ToList()
FirstNamesLists = t.Bs.Select(t2 => t2.FirstNames).ToList(),
FirstFirstName = t.Bs.SelectMany(t2 => t2.FirstNames).First(),
FirstOrDefaultFirstName = t.Bs.SelectMany(t2 => t2.FirstNames).FirstOrDefault(),
LastFirstName = t.Bs.SelectMany(t2 => t2.FirstNames).Last(),
LastOrDefaultFirstName = t.Bs.SelectMany(t2 => t2.FirstNames).LastOrDefault(),
FirstFirstNameList = t.Bs.Select(t2 => t2.FirstNames).First(),
FirstOrDefaultFirstNameList = t.Bs.Select(t2 => t2.FirstNames).FirstOrDefault(),
LastFirstNameList = t.Bs.Select(t2 => t2.FirstNames).Last(),
LastOrDefaultFirstNameList = t.Bs.Select(t2 => t2.FirstNames).LastOrDefault()
});
var regularSyntax = regularSyntaxA.ToList();
@ -57,8 +66,17 @@ namespace PoweredSoft.DynamicLinq.Test
.Select(t =>
{
t.Path("Id");
t.PathToList("Bs.FirstNames", "FirstNames", SelectCollectionHandling.Flatten);
t.PathToList("Bs.FirstNames", "FirstNamesLists", SelectCollectionHandling.LeaveAsIs);
t.ToList("Bs.FirstNames", "FirstNames", SelectCollectionHandling.Flatten);
t.ToList("Bs.FirstNames", "FirstNamesLists", SelectCollectionHandling.LeaveAsIs);
t.First("Bs.FirstNames", "FirstFirstName", SelectCollectionHandling.Flatten);
t.FirstOrDefault("Bs.FirstNames", "FirstOrDefaultFirstName", SelectCollectionHandling.Flatten);
t.Last("Bs.FirstNames", "LastFirstName", SelectCollectionHandling.Flatten);
t.LastOrDefault("Bs.FirstNames", "LastOrDefaultFirstName", SelectCollectionHandling.Flatten);
t.First("Bs.FirstNames", "FirstFirstNameList", SelectCollectionHandling.LeaveAsIs);
t.FirstOrDefault("Bs.FirstNames", "FirstOrDefaultFirstNameList", SelectCollectionHandling.LeaveAsIs);
t.Last("Bs.FirstNames", "LastFirstNameList", SelectCollectionHandling.LeaveAsIs);
t.LastOrDefault("Bs.FirstNames", "LastOrDefaultFirstNameList", SelectCollectionHandling.LeaveAsIs);
})
.ToDynamicClassList();
@ -66,9 +84,22 @@ namespace PoweredSoft.DynamicLinq.Test
for(var i = 0; i < regularSyntax.Count; i++)
{
Assert.AreEqual(regularSyntax[i].Id, dynamicSyntax[i].GetDynamicPropertyValue<int>("Id"));
Assert.AreEqual(regularSyntax[i].FirstFirstName, dynamicSyntax[i].GetDynamicPropertyValue<string>("FirstFirstName"));
Assert.AreEqual(regularSyntax[i].FirstOrDefaultFirstName, dynamicSyntax[i].GetDynamicPropertyValue<string>("FirstOrDefaultFirstName"));
Assert.AreEqual(regularSyntax[i].LastFirstName, dynamicSyntax[i].GetDynamicPropertyValue<string>("LastFirstName"));
Assert.AreEqual(regularSyntax[i].LastOrDefaultFirstName, dynamicSyntax[i].GetDynamicPropertyValue<string>("LastOrDefaultFirstName"));
CollectionAssert.AreEqual(regularSyntax[i].FirstFirstNameList, dynamicSyntax[i].GetDynamicPropertyValue<List<string>>("FirstFirstNameList"));
CollectionAssert.AreEqual(regularSyntax[i].FirstOrDefaultFirstNameList, dynamicSyntax[i].GetDynamicPropertyValue<List<string>>("FirstOrDefaultFirstNameList"));
CollectionAssert.AreEqual(regularSyntax[i].LastFirstNameList, dynamicSyntax[i].GetDynamicPropertyValue<List<string>>("LastFirstNameList"));
CollectionAssert.AreEqual(regularSyntax[i].LastOrDefaultFirstNameList, dynamicSyntax[i].GetDynamicPropertyValue<List<string>>("LastOrDefaultFirstNameList"));
QueryableAssert.AreEqual(regularSyntax[i].FirstNames.AsQueryable(), dynamicSyntax[i].GetDynamicPropertyValue<List<string>>("FirstNames").AsQueryable());
var left = regularSyntax[i].FirstNamesLists;
var right = dynamicSyntax[i].GetDynamicPropertyValue<List<List<string>>>("FirstNamesLists");
Assert.AreEqual(left.Count, right.Count);
@ -95,7 +126,7 @@ namespace PoweredSoft.DynamicLinq.Test
var querySelect = query.Select(t =>
{
t.NullChecking(true);
t.PathToList("Posts.Comments.CommentLikes", selectCollectionHandling: SelectCollectionHandling.Flatten);
t.ToList("Posts.Comments.CommentLikes", selectCollectionHandling: SelectCollectionHandling.Flatten);
});
var b = querySelect.ToDynamicClassList();

View File

@ -49,14 +49,13 @@ namespace PoweredSoft.DynamicLinq
Sum,
Average,
ToList,
PathToList,
Path,
Min,
Max,
LastOrDefault,
FirstOrDefault,
Last,
First
First,
}
public enum SelectCollectionHandling

View File

@ -69,17 +69,28 @@ namespace PoweredSoft.DynamicLinq.Fluent
public SelectBuilder LongCount(string propertyName) => Aggregate(null, SelectTypes.LongCount, propertyName);
public SelectBuilder Sum(string path, string propertyName = null) => Aggregate(path, SelectTypes.Sum, propertyName);
public SelectBuilder Average(string path, string propertyName = null) => Aggregate(path, SelectTypes.Average, propertyName);
public void Min(string path, string propertyName = null) => Aggregate(path, SelectTypes.Min, propertyName);
public void Max(string path, string propertyName = null) => Aggregate(path, SelectTypes.Max, propertyName);
public SelectBuilder Min(string path, string propertyName = null) => Aggregate(path, SelectTypes.Min, propertyName);
public SelectBuilder Max(string path, string propertyName = null) => Aggregate(path, SelectTypes.Max, propertyName);
public SelectBuilder ToList(string propertyName) => Aggregate(null, SelectTypes.ToList, propertyName);
public SelectBuilder LastOrDefault(string propertyName) => Aggregate(null, SelectTypes.LastOrDefault, propertyName);
public SelectBuilder FirstOrDefault(string propertyName) => Aggregate(null, SelectTypes.FirstOrDefault, propertyName);
public SelectBuilder Last(string propertyName) => Aggregate(null, SelectTypes.Last, propertyName);
public SelectBuilder First(string propertyName) => Aggregate(null, SelectTypes.First, propertyName);
public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
=> Aggregate(path, SelectTypes.PathToList, propertyName: propertyName, selectCollectionHandling: selectCollectionHandling);
public SelectBuilder ToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
=> Aggregate(path, SelectTypes.ToList, propertyName: propertyName, selectCollectionHandling: selectCollectionHandling);
public void LastOrDefault(string propertyName) => Aggregate(null, SelectTypes.LastOrDefault, propertyName);
public void FirstOrDefault(string propertyName) => Aggregate(null, SelectTypes.FirstOrDefault, propertyName);
public void Last(string propertyName) => Aggregate(null, SelectTypes.Last, propertyName);
public void First(string propertyName) => Aggregate(null, SelectTypes.First, propertyName);
public SelectBuilder First(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
=> Aggregate(path, SelectTypes.First, propertyName: propertyName, selectCollectionHandling: selectCollectionHandling);
public SelectBuilder FirstOrDefault(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
=> Aggregate(path, SelectTypes.FirstOrDefault, propertyName: propertyName, selectCollectionHandling: selectCollectionHandling);
public SelectBuilder Last(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
=> Aggregate(path, SelectTypes.Last, propertyName: propertyName, selectCollectionHandling: selectCollectionHandling);
public SelectBuilder LastOrDefault(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
=> Aggregate(path, SelectTypes.LastOrDefault, propertyName: propertyName, selectCollectionHandling: selectCollectionHandling);
public virtual IQueryable Build()
{

View File

@ -246,25 +246,37 @@ namespace PoweredSoft.DynamicLinq.Helpers
resolver.Resolve();
return resolver.GetResultBodyExpression();
}
else if (selectType == SelectTypes.PathToList)
{
var parser = new ExpressionParser(parameter, path);
var resolver = new PathExpressionResolver(parser);
resolver.NullChecking = nullChecking;
resolver.CollectionHandling = selectCollectionHandling;
resolver.Resolve();
var expr = (resolver.Result as LambdaExpression).Body;
var notGroupedType = expr.Type.GenericTypeArguments.FirstOrDefault();
if (notGroupedType == null)
throw new Exception($"Path must be a Enumerable<T> but its a {expr.Type}");
else if (selectType == SelectTypes.ToList)
return CreateSelectExpressionPathWithMethodName(parameter, path, selectCollectionHandling, nullChecking, "ToList");
else if (selectType == SelectTypes.First)
return CreateSelectExpressionPathWithMethodName(parameter, path, selectCollectionHandling, nullChecking, "First");
else if (selectType == SelectTypes.FirstOrDefault)
return CreateSelectExpressionPathWithMethodName(parameter, path, selectCollectionHandling, nullChecking, "FirstOrDefault");
else if (selectType == SelectTypes.Last)
return CreateSelectExpressionPathWithMethodName(parameter, path, selectCollectionHandling, nullChecking, "Last");
else if (selectType == SelectTypes.LastOrDefault)
return CreateSelectExpressionPathWithMethodName(parameter, path, selectCollectionHandling, nullChecking, "LastOrDefault");
var body = Expression.Call(typeof(Enumerable), "ToList", new[] { notGroupedType }, expr) as Expression;
return body;
}
throw new NotSupportedException($"unkown select type {selectType}");
}
private static Expression CreateSelectExpressionPathWithMethodName(ParameterExpression parameter, string path, SelectCollectionHandling selectCollectionHandling, bool nullChecking, string methodName)
{
var parser = new ExpressionParser(parameter, path);
var resolver = new PathExpressionResolver(parser);
resolver.NullChecking = nullChecking;
resolver.CollectionHandling = selectCollectionHandling;
resolver.Resolve();
var expr = (resolver.Result as LambdaExpression).Body;
var notGroupedType = expr.Type.GenericTypeArguments.FirstOrDefault();
if (notGroupedType == null)
throw new Exception($"Path must be a Enumerable<T> but its a {expr.Type}");
var body = Expression.Call(typeof(Enumerable), methodName, new[] { notGroupedType }, expr) as Expression;
return body;
}
private static bool IsGrouping(IQueryable query)
{
// TODO needs to be alot better than this, but it will do for now.

View File

@ -99,11 +99,13 @@ someQsomeQueryableOfTueryable.Count();
### Select
> Note **PathToList** has been renamed to just **ToList** it seemed redudant, sorry for breaking change.
```csharp
var querySelect = query.Select(t =>
{
t.NullChecking(true); // not obligated but usefull for in memory queries.
t.PathToList("Posts.Comments.CommentLikes", selectCollectionHandling: SelectCollectionHandling.Flatten);
t.ToList("Posts.Comments.CommentLikes", selectCollectionHandling: SelectCollectionHandling.Flatten);
t.Path("FirstName");
t.Path("LastName", "ChangePropertyNameOfLastName");
});