diff --git a/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj b/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj
index e2bbfbf..e41965e 100644
--- a/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj
+++ b/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj
@@ -66,6 +66,7 @@
+
diff --git a/PoweredSoft.DynamicLinq.Test/SelectTests.cs b/PoweredSoft.DynamicLinq.Test/SelectTests.cs
new file mode 100644
index 0000000..64af1a4
--- /dev/null
+++ b/PoweredSoft.DynamicLinq.Test/SelectTests.cs
@@ -0,0 +1,47 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using PoweredSoft.DynamicLinq.Dal.Pocos;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PoweredSoft.DynamicLinq.Test
+{
+ [TestClass]
+ public class SelectTests
+ {
+ [TestMethod]
+ public void TestSelect()
+ {
+ var regularSyntax = TestData.Authors
+ .AsQueryable()
+ .Select(t => new
+ {
+ Id = t.Id,
+ AuthorFirstName = t.FirstName,
+ AuthorLastName = t.LastName,
+ Posts = t.Posts.ToList()
+ }).ToList();
+
+ var dynamicSyntax = TestData.Authors
+ .AsQueryable()
+ .Select(t =>
+ {
+ t.Path("Id");
+ t.Path("FirstName", "AuthorFirstName");
+ t.Path("LastName", "AuthorLastName");
+ t.PathToList("Posts");
+ }).ToDynamicClassList();
+
+ Assert.AreEqual(regularSyntax.Count, dynamicSyntax.Count);
+ for(var i = 0; i < regularSyntax.Count; i++)
+ {
+ Assert.AreEqual(regularSyntax[i].Id, dynamicSyntax[i].GetDynamicPropertyValue("Id"));
+ Assert.AreEqual(regularSyntax[i].AuthorFirstName, dynamicSyntax[i].GetDynamicPropertyValue("AuthorFirstName"));
+ Assert.AreEqual(regularSyntax[i].AuthorLastName, dynamicSyntax[i].GetDynamicPropertyValue("AuthorLastName"));
+ Helpers.QueryableAssert.AreEqual(regularSyntax[i].Posts.AsQueryable(), dynamicSyntax[i].GetDynamicPropertyValue>("Posts").AsQueryable());
+ }
+ }
+ }
+}
diff --git a/PoweredSoft.DynamicLinq/Constants.cs b/PoweredSoft.DynamicLinq/Constants.cs
index 1d3f4f0..4f6b27f 100644
--- a/PoweredSoft.DynamicLinq/Constants.cs
+++ b/PoweredSoft.DynamicLinq/Constants.cs
@@ -48,7 +48,9 @@ namespace PoweredSoft.DynamicLinq
LongCount,
Sum,
Average,
- ToList
+ ToList,
+ PathToList,
+ Path
}
internal static class Constants
diff --git a/PoweredSoft.DynamicLinq/Fluent/Select/SelectBuilder.cs b/PoweredSoft.DynamicLinq/Fluent/Select/SelectBuilder.cs
index 9f6833c..420c7ae 100644
--- a/PoweredSoft.DynamicLinq/Fluent/Select/SelectBuilder.cs
+++ b/PoweredSoft.DynamicLinq/Fluent/Select/SelectBuilder.cs
@@ -51,6 +51,23 @@ namespace PoweredSoft.DynamicLinq.Fluent
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);
@@ -116,6 +133,23 @@ namespace PoweredSoft.DynamicLinq.Fluent
return this;
}
+ public SelectBuilder PathToList(string path, string propertyName = null)
+ {
+ if (propertyName == null)
+ propertyName = path.Split('.').LastOrDefault();
+
+ throwIfUsedOrEmpty(propertyName);
+
+ Parts.Add(new SelectPart
+ {
+ Path = path,
+ PropertyName = propertyName,
+ SelectType = SelectTypes.PathToList
+ });
+
+ return this;
+ }
+
public virtual IQueryable Build()
{
if (Empty)
diff --git a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs
index 128aa15..fcd1a6d 100644
--- a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs
+++ b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs
@@ -196,11 +196,31 @@ namespace PoweredSoft.DynamicLinq.Helpers
private static Expression CreateSelectExpression(IQueryable query, ParameterExpression parameter, SelectTypes selectType, string path)
{
if (!IsGrouping(query))
- throw new NotSupportedException("Select without grouping is not supported yet.");
+ return CreateSelectExpressionRegular(query, parameter, selectType, path);
return CreateSelectExpressionForGrouping(query, parameter, selectType, path);
}
+ private static Expression CreateSelectExpressionRegular(IQueryable query, ParameterExpression parameter, SelectTypes selectType, string path)
+ {
+ if (selectType == SelectTypes.Path)
+ {
+ return ResolvePathForExpression(parameter, path);
+ }
+ else if (selectType == SelectTypes.PathToList)
+ {
+ var expr = ResolvePathForExpression(parameter, path);
+ var notGroupedType = expr.Type.GenericTypeArguments.FirstOrDefault();
+ if (notGroupedType == null)
+ throw new Exception($"Path must be a Enumerable but its a {expr.Type}");
+
+ var body = Expression.Call(typeof(Enumerable), "ToList", new[] { notGroupedType }, expr);
+ return body;
+ }
+
+ throw new NotSupportedException($"unkown select type {selectType}");
+ }
+
private static bool IsGrouping(IQueryable query)
{
// TODO needs to be alot better than this, but it will do for now.