adding lots more select types support.
This commit is contained in:
parent
7269071a3a
commit
dcaf114a09
@ -73,7 +73,13 @@ namespace PoweredSoft.DynamicLinq.Test
|
|||||||
LongCount = t.LongCount(),
|
LongCount = t.LongCount(),
|
||||||
NetSales = t.Sum(t2 => t2.NetSales),
|
NetSales = t.Sum(t2 => t2.NetSales),
|
||||||
TaxAverage = t.Average(t2 => t2.Tax),
|
TaxAverage = t.Average(t2 => t2.Tax),
|
||||||
Sales = t.ToList()
|
Sales = t.ToList(),
|
||||||
|
MaxNetSales = t.Max(t2 => t2.NetSales),
|
||||||
|
MinNetSales = t.Min(t2 => t2.NetSales),
|
||||||
|
First = t.First(),
|
||||||
|
Last = t.Last(),
|
||||||
|
FirstOrDefault = t.FirstOrDefault(),
|
||||||
|
LastOrDefault = t.LastOrDefault()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -87,6 +93,12 @@ namespace PoweredSoft.DynamicLinq.Test
|
|||||||
t.LongCount("LongCount");
|
t.LongCount("LongCount");
|
||||||
t.Sum("NetSales");
|
t.Sum("NetSales");
|
||||||
t.Average("Tax", "TaxAverage");
|
t.Average("Tax", "TaxAverage");
|
||||||
|
t.Max("NetSales", "MaxNetSales");
|
||||||
|
t.Min("NetSales", "MinNetSales");
|
||||||
|
t.First("First");
|
||||||
|
t.Last("Last");
|
||||||
|
t.FirstOrDefault("FirstOrDefault");
|
||||||
|
t.LastOrDefault("LastOrDefault");
|
||||||
t.ToList("Sales");
|
t.ToList("Sales");
|
||||||
})
|
})
|
||||||
.ToDynamicClassList();
|
.ToDynamicClassList();
|
||||||
@ -101,6 +113,14 @@ namespace PoweredSoft.DynamicLinq.Test
|
|||||||
Assert.AreEqual(left.Count, right.GetDynamicPropertyValue("Count"));
|
Assert.AreEqual(left.Count, right.GetDynamicPropertyValue("Count"));
|
||||||
Assert.AreEqual(left.LongCount, right.GetDynamicPropertyValue("LongCount"));
|
Assert.AreEqual(left.LongCount, right.GetDynamicPropertyValue("LongCount"));
|
||||||
Assert.AreEqual(left.TaxAverage, right.GetDynamicPropertyValue("TaxAverage"));
|
Assert.AreEqual(left.TaxAverage, right.GetDynamicPropertyValue("TaxAverage"));
|
||||||
|
Assert.AreEqual(left.MinNetSales, right.GetDynamicPropertyValue("MinNetSales"));
|
||||||
|
Assert.AreEqual(left.MaxNetSales, right.GetDynamicPropertyValue("MaxNetSales"));
|
||||||
|
|
||||||
|
Assert.AreEqual(left.First, right.GetDynamicPropertyValue("First"));
|
||||||
|
Assert.AreEqual(left.FirstOrDefault, right.GetDynamicPropertyValue("FirstOrDefault"));
|
||||||
|
Assert.AreEqual(left.Last, right.GetDynamicPropertyValue("Last"));
|
||||||
|
Assert.AreEqual(left.LastOrDefault, right.GetDynamicPropertyValue("LastOrDefault"));
|
||||||
|
|
||||||
QueryableAssert.AreEqual(left.Sales.AsQueryable(), right.GetDynamicPropertyValue<List<MockSale>>("Sales").AsQueryable());
|
QueryableAssert.AreEqual(left.Sales.AsQueryable(), right.GetDynamicPropertyValue<List<MockSale>>("Sales").AsQueryable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,13 @@ namespace PoweredSoft.DynamicLinq
|
|||||||
Average,
|
Average,
|
||||||
ToList,
|
ToList,
|
||||||
PathToList,
|
PathToList,
|
||||||
Path
|
Path,
|
||||||
|
Min,
|
||||||
|
Max,
|
||||||
|
LastOrDefault,
|
||||||
|
FirstOrDefault,
|
||||||
|
Last,
|
||||||
|
First
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SelectCollectionHandling
|
public enum SelectCollectionHandling
|
||||||
|
@ -42,25 +42,11 @@ namespace PoweredSoft.DynamicLinq.Fluent
|
|||||||
throw new Exception($"{propertyName} is already used");
|
throw new Exception($"{propertyName} is already used");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SelectBuilder Key(string propertyName, string path = null)
|
public SelectBuilder Aggregate(string path, SelectTypes type, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
|
||||||
{
|
{
|
||||||
if (propertyName == null)
|
if (propertyName == null && path == null)
|
||||||
propertyName = path.Split('.').LastOrDefault();
|
throw new Exception("if property name is not specified, a path must be supplied.");
|
||||||
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
Path = path == null ? "Key" : $"Key.{path}",
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.Key
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder Aggregate(string path, SelectTypes type, string propertyName = null)
|
|
||||||
{
|
|
||||||
if (propertyName == null)
|
if (propertyName == null)
|
||||||
propertyName = path.Split('.').LastOrDefault();
|
propertyName = path.Split('.').LastOrDefault();
|
||||||
|
|
||||||
@ -70,112 +56,31 @@ namespace PoweredSoft.DynamicLinq.Fluent
|
|||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
PropertyName = propertyName,
|
PropertyName = propertyName,
|
||||||
SelectType = type
|
SelectType = type,
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder Path(string path, string propertyName = null)
|
|
||||||
{
|
|
||||||
if (propertyName == null)
|
|
||||||
propertyName = path.Split('.').LastOrDefault();
|
|
||||||
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
Path = path,
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.Path
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder Count(string propertyName)
|
|
||||||
{
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.Count
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder LongCount(string propertyName)
|
|
||||||
{
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.LongCount
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder Sum(string path, string propertyName = null)
|
|
||||||
{
|
|
||||||
if (propertyName == null)
|
|
||||||
propertyName = path.Split('.').LastOrDefault();
|
|
||||||
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
Path = path,
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.Sum
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder Average(string path, string propertyName = null)
|
|
||||||
{
|
|
||||||
if (propertyName == null)
|
|
||||||
propertyName = path.Split('.').LastOrDefault();
|
|
||||||
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
Path = path,
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.Average
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder ToList(string propertyName)
|
|
||||||
{
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.ToList
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
|
|
||||||
{
|
|
||||||
if (propertyName == null)
|
|
||||||
propertyName = path.Split('.').LastOrDefault();
|
|
||||||
|
|
||||||
ThrowIfUsedOrEmpty(propertyName);
|
|
||||||
|
|
||||||
Parts.Add(new SelectPart
|
|
||||||
{
|
|
||||||
Path = path,
|
|
||||||
PropertyName = propertyName,
|
|
||||||
SelectType = SelectTypes.PathToList,
|
|
||||||
SelectCollectionHandling = selectCollectionHandling
|
SelectCollectionHandling = selectCollectionHandling
|
||||||
});
|
});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SelectBuilder Key(string propertyName, string path = null) => Aggregate(path == null ? "Key" : $"Key.{path}", SelectTypes.Key, propertyName);
|
||||||
|
public SelectBuilder Path(string path, string propertyName = null) => Aggregate(path, SelectTypes.Path, propertyName);
|
||||||
|
public SelectBuilder Count(string propertyName) => Aggregate(null, SelectTypes.Count, propertyName);
|
||||||
|
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 ToList(string propertyName) => Aggregate(null, SelectTypes.ToList, propertyName);
|
||||||
|
|
||||||
|
public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
|
||||||
|
=> Aggregate(path, SelectTypes.PathToList, 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 virtual IQueryable Build()
|
public virtual IQueryable Build()
|
||||||
{
|
{
|
||||||
if (Empty)
|
if (Empty)
|
||||||
|
@ -175,12 +175,54 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
|||||||
var body = Expression.Call(typeof(Enumerable), "Sum", new[] { notGroupedType }, parameter, innerMemberLambda);
|
var body = Expression.Call(typeof(Enumerable), "Sum", new[] { notGroupedType }, parameter, innerMemberLambda);
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
else if (selectType == SelectTypes.Min)
|
||||||
|
{
|
||||||
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
|
var innerParameter = Expression.Parameter(notGroupedType);
|
||||||
|
var innerMemberExpression = ResolvePathForExpression(innerParameter, path);
|
||||||
|
var innerMemberLambda = Expression.Lambda(innerMemberExpression, innerParameter);
|
||||||
|
var body = Expression.Call(typeof(Enumerable), "Min", new[] { notGroupedType }, parameter, innerMemberLambda);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
else if (selectType == SelectTypes.Max)
|
||||||
|
{
|
||||||
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
|
var innerParameter = Expression.Parameter(notGroupedType);
|
||||||
|
var innerMemberExpression = ResolvePathForExpression(innerParameter, path);
|
||||||
|
var innerMemberLambda = Expression.Lambda(innerMemberExpression, innerParameter);
|
||||||
|
var body = Expression.Call(typeof(Enumerable), "Max", new[] { notGroupedType }, parameter, innerMemberLambda);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
else if (selectType == SelectTypes.ToList)
|
else if (selectType == SelectTypes.ToList)
|
||||||
{
|
{
|
||||||
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
var body = Expression.Call(typeof(Enumerable), "ToList", new[] { notGroupedType }, parameter);
|
var body = Expression.Call(typeof(Enumerable), "ToList", new[] { notGroupedType }, parameter);
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
else if (selectType == SelectTypes.First)
|
||||||
|
{
|
||||||
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
|
var body = Expression.Call(typeof(Enumerable), "First", new[] { notGroupedType }, parameter);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
else if (selectType == SelectTypes.Last)
|
||||||
|
{
|
||||||
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
|
var body = Expression.Call(typeof(Enumerable), "Last", new[] { notGroupedType }, parameter);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
else if (selectType == SelectTypes.FirstOrDefault)
|
||||||
|
{
|
||||||
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
|
var body = Expression.Call(typeof(Enumerable), "FirstOrDefault", new[] { notGroupedType }, parameter);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
else if (selectType == SelectTypes.LastOrDefault)
|
||||||
|
{
|
||||||
|
var notGroupedType = parameter.Type.GenericTypeArguments[1];
|
||||||
|
var body = Expression.Call(typeof(Enumerable), "LastOrDefault", new[] { notGroupedType }, parameter);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
throw new NotSupportedException($"unkown select type {selectType}");
|
throw new NotSupportedException($"unkown select type {selectType}");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user