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 Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>

<PropertyGroup>
<VersionPrefix>1.0.9.2</VersionPrefix>
<VersionPrefix>1.0.10</VersionPrefix>
</PropertyGroup>

<Choose>
Expand Down
22 changes: 22 additions & 0 deletions src-console/ConsoleAppEF2.0.2_InMemory/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ namespace ConsoleAppEF2
{
class Program
{
class User
{
public string Name { get; set; }

public string GetDisplayName(bool a, bool b, bool c)
{
return Name + "GetDisplayName";
}
}

class C : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
{
public HashSet<Type> GetCustomTypes()
Expand Down Expand Up @@ -69,6 +79,15 @@ static void Main(string[] args)
};
Console.WriteLine("all {0}", JsonConvert.SerializeObject(all, Formatting.Indented));

var projects = new[]
{
new { UserShares = new [] { new User { Name = "John" } } }
}.AsQueryable();

var filter = "UserShares.Any(GetDisplayName(true,true,false).Contains(\"John\"))";
var filtered = projects.Where(filter);
Console.WriteLine("filtered {0}", JsonConvert.SerializeObject(filtered, Formatting.Indented));

var config = new ParsingConfig
{
CustomTypeProvider = new C()
Expand All @@ -83,6 +102,9 @@ static void Main(string[] args)
context.Cars.Add(new Car { Brand = "Alfa", Color = "Black", Vin = "a%bc", Year = "1979", DateLastModified = dateLastModified.AddDays(3) });
context.SaveChanges();

var methodTest = context.Cars.Select("it.X(true, \"tst\").Contains(\"Blue\")");
Console.WriteLine("methodTest {0}", JsonConvert.SerializeObject(methodTest, Formatting.Indented));

var carSingleOrDefault = context.Cars.SingleOrDefault(config, "Brand = \"Ford\"");
Console.WriteLine("carSingleOrDefault {0}", JsonConvert.SerializeObject(carSingleOrDefault, Formatting.Indented));

Expand Down
5 changes: 5 additions & 0 deletions src-console/ConsoleAppEF2.0/Database/Car.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,10 @@ public class Car

[Required]
public DateTime DateLastModified { get; set; }

public string X(bool b, string s)
{
return b + s + Color;
}
}
}
148 changes: 15 additions & 133 deletions src-console/ConsoleAppEF2.1.1_InMemory/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Reflection;
using ConsoleAppEF2.Database;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ConsoleAppEF2
{
Expand All @@ -18,11 +17,17 @@ public class NestedDto
public string Name { get; set; }

public NestedDto2 NestedDto2 { get; set; }
}

public class NestedDto2
{
public string Name2 { get; set; }

public int Id { get; set; }
public NestedDto3 NestedDto3 { get; set; }
}

public class NestedDto2
public class NestedDto3
{
public string Name2 { get; set; }

Expand Down Expand Up @@ -50,129 +55,18 @@ public Type ResolveType(string typeName)
}
}

private static object GetObj()
{
return new
{
Id = 5,
Value = 400
};
}

class X : DynamicClass
{

}

private static IQueryable GetQueryable()
{
var random = new Random((int)DateTime.Now.Ticks);

var jt = typeof(JToken);

var em = jt.GetTypeInfo().GetDeclaredMethods("op_Explicit");
var im = jt.GetTypeInfo().GetDeclaredMethods("op_Explicit");

var j = new JObject
{
{ "Id", new JValue(9) },
{ "Name", new JValue("Test") }
};

//(j["Id"] as JValue).Value

IQueryable jarray = new[] { j }.AsQueryable();
var jresult = jarray.Select("new (int(Id) as Id, string(Name) as Name)");

var an = jresult.Any("Id > 4");


var dx = new X();
dx["Id"] = 5;

IQueryable srcDX = new[] { dx }.AsQueryable();
var b = srcDX.Select("new (Id.ToString() as Id)");
var anyDX = b.Any("int.Parse(Id) > 4");

var x = Enumerable.Range(0, 10).Select(i => new
{
Id = i,
Value = random.Next()
}).AsQueryable();

//var any = x.Any("Id > 4");

//var obj = new
//{
// Id = 5,
// Value = random.Next()
//};
//var x2 = Enumerable.Range(0, 1).Select(_ => obj).AsQueryable();
//var any2 = x.Any("Id > 4");

//var o = GetObj();
//var t = o.GetType();
//IQueryable source = new[] { o }.AsQueryable();
//// source.ElementType = t;

//var x2b = new[] { o }.AsQueryable();
//var any2function = x2b.Any(null, "Id > 4", t);

//var any2b = x2b.Any("Id > 4");

//var x3 = new[] { obj }.AsQueryable();
//var any3 = x3.Any("Id > 4");

return x.Select("new (it as Id, @0 as Value)", random.Next());
// return x.AsQueryable(); //x.AsQueryable().Select("new (Id, Value)");
}

public static IQueryable Transform(this IQueryable source, Type resultType)
static void Main(string[] args)
{
var resultProperties = resultType.GetProperties().Where(p => p.CanWrite);
var q = new[] { new NestedDto(), new NestedDto { NestedDto2 = new NestedDto2 { NestedDto3 = new NestedDto3 { Id = 42 } } } }.AsQueryable();

ParameterExpression s = Expression.Parameter(source.ElementType, "s");
var np1 = q.Select("np(it.NestedDto2.NestedDto3.Id, 0)");
var npResult1 = np1.ToDynamicList<int>();
Console.WriteLine("npResult1 {0}", JsonConvert.SerializeObject(npResult1, Formatting.Indented));

var memberBindings =
resultProperties.Select(p =>
Expression.Bind(resultType.GetMember(p.Name)[0], Expression.Property(s, p.Name))).OfType<MemberBinding>();
var np2 = q.Select("np(it.NestedDto2.NestedDto3.Id)");
var npResult2 = np2.ToDynamicList<int?>();
Console.WriteLine("npResult2 {0}", JsonConvert.SerializeObject(npResult2, Formatting.Indented));

Expression memberInit = Expression.MemberInit(
Expression.New(resultType),
memberBindings
);

var memberInitLambda = Expression.Lambda(memberInit, s);

var typeArgs = new[]
{
source.ElementType,
memberInit.Type
};

var mc = Expression.Call(typeof(Queryable), "Select", typeArgs, source.Expression, memberInitLambda);

var query = source.Provider.CreateQuery(mc);

return query;
}

public static IQueryable<T> EmptyQueryByExample<T>(this T _) => Enumerable.Empty<T>().AsQueryable();


private static TResult Execute<TResult>(MethodInfo operatorMethodInfo, IQueryable source, Expression expression, Type t = null)
{
operatorMethodInfo = operatorMethodInfo.GetGenericArguments().Length == 2
? operatorMethodInfo.MakeGenericMethod(t == null ? source.ElementType : t, typeof(TResult))
: operatorMethodInfo.MakeGenericMethod(t == null ? source.ElementType : t);

var optimized = Expression.Call(null, operatorMethodInfo, source.Expression, expression);
return source.Provider.Execute<TResult>(optimized);
}

static void Main(string[] args)
{
var q = new[] { new NestedDto(), new NestedDto { NestedDto2 = new NestedDto2 { Id = 42 } } }.AsQueryable();
var r1 = q.Select("it != null && it.NestedDto2 != null ? it.NestedDto2.Id : null");
var list1 = r1.ToDynamicList<int?>();

Expand All @@ -191,18 +85,6 @@ static void Main(string[] args)
Console.WriteLine(projectedData.First().Name);
Console.WriteLine(projectedData.Last().Name);

IQueryable qry = GetQueryable();

var result = qry.Select("it").OrderBy("Value");
try
{
Console.WriteLine("result {0}", JsonConvert.SerializeObject(result, Formatting.Indented));
}
catch (Exception)
{
// Console.WriteLine(e);
}

var all = new
{
test1 = new List<int> { 1, 2, 3 }.ToDynamicList(typeof(int)),
Expand Down
75 changes: 75 additions & 0 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System.Collections.Generic;
using System.Globalization;
using System.Linq.Dynamic.Core.Validation;
using System.Linq.Expressions;
Expand Down Expand Up @@ -234,5 +235,79 @@ private void WrapConstantExpressions(ref Expression left, ref Expression right)
_constantExpressionWrapper.Wrap(ref right);
}
}

public Expression GenerateAndAlsoNotNullExpression(Expression sourceExpression)
{
var expresssions = CollectExpressions(sourceExpression);
if (!expresssions.Any())
{
return null;
}

// Reverse the list
expresssions.Reverse();

// Convert all expressions into '!= null'
var binaryExpressions = expresssions.Select(expression => Expression.NotEqual(expression, Constants.NullLiteral)).ToArray();

// Convert all binary expressions into `AndAlso(...)`
var andAlsoExpression = binaryExpressions[0];
for (int i = 1; i < binaryExpressions.Length; i++)
{
andAlsoExpression = Expression.AndAlso(andAlsoExpression, binaryExpressions[i]);
}

return andAlsoExpression;
}

private static Expression GetMemberExpression(Expression expression)
{
if (expression is ParameterExpression parameterExpression)
{
return parameterExpression;
}

if (expression is MemberExpression memberExpression)
{
return memberExpression;
}

if (expression is LambdaExpression lambdaExpression)
{
if (lambdaExpression.Body is MemberExpression bodyAsMemberExpression)
{
return bodyAsMemberExpression;
}

if (lambdaExpression.Body is UnaryExpression bodyAsunaryExpression)
{
return bodyAsunaryExpression.Operand;
}
}

return null;
}

private static List<Expression> CollectExpressions(Expression sourceExpression)
{
var list = new List<Expression>();
Expression expression = GetMemberExpression(sourceExpression);

while (expression is MemberExpression memberExpression)
{
expression = GetMemberExpression(memberExpression.Expression);
if (expression is MemberExpression)
{
list.Add(expression);
}
}

if (expression is ParameterExpression)
{
list.Add(expression);
}

return list;
}
}
}
Loading