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
8 changes: 8 additions & 0 deletions src-console/ConsoleAppEF1.1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ static void Main(string[] args)
{
using (var db = new MyDbContext())
{
var all = new
{
test1 = new List<int> { 1, 2, 3 }.ToDynamicList(typeof(int)),
test2 = new List<dynamic> { 4, 5, 6 }.ToDynamicList(typeof(int)),
test3 = new List<object> { 7, 8, 9 }.ToDynamicList(typeof(int))
};
Console.WriteLine("all {0}", JsonConvert.SerializeObject(all, Formatting.Indented));

var persons = new List<Person>
{
new Person { Name = "a", Age = 18, Address = new Address { Street = "s1" } },
Expand Down
21 changes: 15 additions & 6 deletions src-console/ConsoleAppEF2.0/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@ public HashSet<Type> GetCustomTypes()

static void Main(string[] args)
{
GlobalConfig.CustomTypeProvider = new C();
var all = new
{
test1 = new List<int> { 1, 2, 3 }.ToDynamicList(typeof(int)),
test2 = new List<dynamic> { 4, 5, 6 }.ToDynamicList(typeof(int)),
test3 = new List<object> { 7, 8, 9 }.ToDynamicList(typeof(int))
};
Console.WriteLine("all {0}", JsonConvert.SerializeObject(all, Formatting.Indented));

var config = new ParsingConfig();
config.CustomTypeProvider = new C();

var context = new TestContext();

Expand All @@ -42,7 +51,7 @@ static void Main(string[] args)
context.SaveChanges();
}

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

var carsLike1 =
Expand All @@ -54,16 +63,16 @@ where EF.Functions.Like(c.Brand, "%a%")
var cars2Like = context.Cars.Where(c => EF.Functions.Like(c.Brand, "%a%"));
Console.WriteLine("cars2Like {0}", JsonConvert.SerializeObject(cars2Like, Formatting.Indented));

var dynamicCarsLike1 = context.Cars.Where("TestContext.Like(Brand, \"%a%\")");
var dynamicCarsLike1 = context.Cars.Where(config, "TestContext.Like(Brand, \"%a%\")");
Console.WriteLine("dynamicCarsLike1 {0}", JsonConvert.SerializeObject(dynamicCarsLike1, Formatting.Indented));

var dynamicCarsLike2 = context.Cars.Where("TestContext.Like(Brand, \"%d%\")");
var dynamicCarsLike2 = context.Cars.Where(config, "TestContext.Like(Brand, \"%d%\")");
Console.WriteLine("dynamicCarsLike2 {0}", JsonConvert.SerializeObject(dynamicCarsLike2, Formatting.Indented));

var dynamicFunctionsLike1 = context.Cars.Where("DynamicFunctions.Like(Brand, \"%a%\")");
var dynamicFunctionsLike1 = context.Cars.Where(config, "DynamicFunctions.Like(Brand, \"%a%\")");
Console.WriteLine("dynamicFunctionsLike1 {0}", JsonConvert.SerializeObject(dynamicFunctionsLike1, Formatting.Indented));

var dynamicFunctionsLike2 = context.Cars.Where("DynamicFunctions.Like(Vin, \"%a.%b%\", \".\")");
var dynamicFunctionsLike2 = context.Cars.Where(config, "DynamicFunctions.Like(Vin, \"%a.%b%\", \".\")");
Console.WriteLine("dynamicFunctionsLike2 {0}", JsonConvert.SerializeObject(dynamicFunctionsLike2, Formatting.Indented));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
<Reference Include="Linq.Expression.Optimizer, Version=1.0.6.0, Culture=neutral, PublicKeyToken=34b6af2337893e15, processorArchitecture=MSIL">
<HintPath>..\..\packages\Linq.Expression.Optimizer.1.0.9\lib\net45\Linq.Expression.Optimizer.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
Expand Down
10 changes: 10 additions & 0 deletions src-console/ConsoleApp_net452_EF6/Program.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ConsoleApp_net452_EF6.Entities;
using System.Linq.Dynamic.Core;
using Newtonsoft.Json;

namespace ConsoleApp_net452_EF6
{
class Program
{
static void Main(string[] args)
{
var all = new
{
test1 = new List<int> { 1, 2, 3 }.ToDynamicList(typeof(int)),
test2 = new List<dynamic> { 4, 5, 6 }.ToDynamicList(typeof(int)),
test3 = new List<object> { 7, 8, 9 }.ToDynamicList(typeof(int))
};

Console.WriteLine("all {0}", JsonConvert.SerializeObject(all, Formatting.Indented));
using (var context = new KendoGridDbContext())
{
string search = "2";
Expand Down
1 change: 1 addition & 0 deletions src-console/ConsoleApp_net452_EF6/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
<package id="EntityFramework" version="6.2.0" targetFramework="net452" />
<package id="FSharp.Core" version="4.2.3" targetFramework="net452" />
<package id="Linq.Expression.Optimizer" version="1.0.9" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
</packages>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>Dynamic Linq extensions for EntityFramework which adds Async support</Description>
<AssemblyTitle>EntityFramework.DynamicLinq</AssemblyTitle>
<VersionPrefix>1.0.4.7</VersionPrefix>
<VersionPrefix>1.0.8.0</VersionPrefix>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net45;net46</TargetFrameworks>
<DefineConstants>EF</DefineConstants>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>Dynamic Linq extensions for Microsoft.EntityFrameworkCore which adds Async support</Description>
<AssemblyTitle>Microsoft.EntityFrameworkCore.DynamicLinq</AssemblyTitle>
<VersionPrefix>1.0.4.8</VersionPrefix>
<VersionPrefix>1.0.8.0</VersionPrefix>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net46;netstandard1.3;netstandard2.0;uap10.0</TargetFrameworks>
<DefineConstants>$(DefineConstants);EFCORE</DefineConstants>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ public class DefaultDynamicLinqCustomTypeProvider : AbstractDynamicLinqCustomTyp
public virtual HashSet<Type> GetCustomTypes()
{
if (_customTypes != null)
{
return _customTypes;
}

IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();
_customTypes = new HashSet<Type>(FindTypesMarkedWithDynamicLinqTypeAttribute(assemblies));
return _customTypes;
}
}
}
#endif
#endif
8 changes: 4 additions & 4 deletions src/System.Linq.Dynamic.Core/DynamicEnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ public static dynamic[] ToDynamicArray([NotNull] this IEnumerable source, [NotNu
Check.NotNull(source, nameof(source));
Check.NotNull(type, nameof(type));

object result = ToDynamicArrayGenericMethod.MakeGenericMethod(type).Invoke(source, new object[] { source });
IEnumerable result = (IEnumerable)ToDynamicArrayGenericMethod.MakeGenericMethod(type).Invoke(source, new object[] { source });
#if NET35
return (object[])result;
return CastToArray<object>(result);
#else
return (dynamic[])result;
return CastToArray<dynamic>(result);
#endif
}

Expand Down Expand Up @@ -132,4 +132,4 @@ internal static List<T> CastToList<T>(IEnumerable source)
return source.Cast<T>().ToList();
}
}
}
}
60 changes: 34 additions & 26 deletions src/System.Linq.Dynamic.Core/DynamicExpressionParser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System.Linq.Dynamic.Core.Parser;
using JetBrains.Annotations;
using System.Linq.Dynamic.Core.Validation;
using System.Linq.Expressions;

Expand All @@ -14,43 +15,41 @@ public static class DynamicExpressionParser
/// </summary>
/// <param name="resultType">Type of the result. If not specified, it will be generated dynamically.</param>
/// <param name="expression">The expression.</param>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda([CanBeNull] Type resultType, string expression, params object[] values)
public static LambdaExpression ParseLambda([CanBeNull] ParsingConfig parsingConfig, [CanBeNull] Type resultType, [NotNull] string expression, params object[] values)
{
return ParseLambda(true, resultType, expression, values);
return ParseLambda(parsingConfig, true, resultType, expression, values);
}

/// <summary>
/// Parses an expression into a LambdaExpression.
/// Parses an expression into a LambdaExpression. (Also create a constructor for all the parameters. Note that this doesn't work for Linq-to-Database entities.)
/// </summary>
/// <param name="createParameterCtor">if set to <c>true</c> then also create a constructor for all the parameters. Note that this doesn't work for Linq-to-Database entities.</param>
/// <param name="resultType">Type of the result. If not specified, it will be generated dynamically.</param>
/// <param name="expression">The expression.</param>
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda(bool createParameterCtor, [CanBeNull] Type resultType, string expression, params object[] values)
public static LambdaExpression ParseLambda([CanBeNull] Type resultType, [NotNull] string expression, params object[] values)
{
Check.NotEmpty(expression, nameof(expression));

var parser = new ExpressionParser(new ParameterExpression[0], expression, values, null);

return Expression.Lambda(parser.Parse(resultType, true));
return ParseLambda(null, true, resultType, expression, values);
}

/// <summary>
/// Parses an expression into a LambdaExpression.
/// </summary>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="createParameterCtor">if set to <c>true</c> then also create a constructor for all the parameters. Note that this doesn't work for Linq-to-Database entities.</param>
/// <param name="resultType">Type of the result. If not specified, it will be generated dynamically.</param>
/// <param name="expression">The expression.</param>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda(bool createParameterCtor, [CanBeNull] Type resultType, string expression, ParsingConfig parsingConfig, params object[] values)
public static LambdaExpression ParseLambda([CanBeNull] ParsingConfig parsingConfig, bool createParameterCtor, [CanBeNull] Type resultType, string expression, params object[] values)
{
Check.NotEmpty(expression, nameof(expression));

Expand Down Expand Up @@ -83,7 +82,7 @@ public static LambdaExpression ParseLambda([NotNull] Type itType, [CanBeNull] Ty
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda([NotNull] Type itType, [CanBeNull] Type resultType, string expression, ParsingConfig parsingConfig, params object[] values)
public static LambdaExpression ParseLambda([CanBeNull] ParsingConfig parsingConfig, [NotNull] Type itType, [CanBeNull] Type resultType, string expression, params object[] values)
{
return ParseLambda(true, itType, resultType, expression, parsingConfig, values);
}
Expand All @@ -109,20 +108,20 @@ public static LambdaExpression ParseLambda(bool createParameterCtor, [NotNull] T
/// <summary>
/// Parses an expression into a LambdaExpression.
/// </summary>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="createParameterCtor">if set to <c>true</c> then also create a constructor for all the parameters. Note that this doesn't work for Linq-to-Database entities.</param>
/// <param name="itType">The main type from the dynamic class expression.</param>
/// <param name="resultType">Type of the result. If not specified, it will be generated dynamically.</param>
/// <param name="expression">The expression.</param>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda(bool createParameterCtor, [NotNull] Type itType, [CanBeNull] Type resultType, string expression, ParsingConfig parsingConfig, params object[] values)
public static LambdaExpression ParseLambda([CanBeNull] ParsingConfig parsingConfig, bool createParameterCtor, [NotNull] Type itType, [CanBeNull] Type resultType, string expression, params object[] values)
{
Check.NotNull(itType, nameof(itType));
Check.NotEmpty(expression, nameof(expression));

return ParseLambda(createParameterCtor, new[] { Expression.Parameter(itType, "") }, resultType, expression, parsingConfig, values);
return ParseLambda(parsingConfig, createParameterCtor, new[] { Expression.Parameter(itType, "") }, resultType, expression, values);
}

/// <summary>
Expand All @@ -136,7 +135,22 @@ public static LambdaExpression ParseLambda(bool createParameterCtor, [NotNull] T
[PublicAPI]
public static LambdaExpression ParseLambda([NotNull] ParameterExpression[] parameters, [CanBeNull] Type resultType, string expression, params object[] values)
{
return ParseLambda(true, parameters, resultType, expression, values);
return ParseLambda(null, true, parameters, resultType, expression, values);
}

/// <summary>
/// Parses an expression into a LambdaExpression. (Also create a constructor for all the parameters. Note that this doesn't work for Linq-to-Database entities.)
/// </summary>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="parameters">A array from ParameterExpressions.</param>
/// <param name="resultType">Type of the result. If not specified, it will be generated dynamically.</param>
/// <param name="expression">The expression.</param>
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda([CanBeNull] ParsingConfig parsingConfig, [NotNull] ParameterExpression[] parameters, [CanBeNull] Type resultType, string expression, params object[] values)
{
return ParseLambda(parsingConfig, true, parameters, resultType, expression, values);
}

/// <summary>
Expand All @@ -149,29 +163,23 @@ public static LambdaExpression ParseLambda([NotNull] ParameterExpression[] param
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda(bool createParameterCtor, [NotNull] ParameterExpression[] parameters, [CanBeNull] Type resultType, string expression, params object[] values)
public static LambdaExpression ParseLambda(bool createParameterCtor, [NotNull] ParameterExpression[] parameters, [CanBeNull] Type resultType, [NotNull] string expression, params object[] values)
{
Check.NotNull(parameters, nameof(parameters));
Check.Condition(parameters, p => p.Count(x => x == null) == 0, nameof(parameters));
Check.NotEmpty(expression, nameof(expression));

var parser = new ExpressionParser(parameters, expression, values, null);

return Expression.Lambda(parser.Parse(resultType, createParameterCtor), parameters);
return ParseLambda(null, createParameterCtor, parameters, resultType, expression, values);
}

/// <summary>
/// Parses an expression into a LambdaExpression.
/// </summary>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="createParameterCtor">if set to <c>true</c> then also create a constructor for all the parameters. Note that this doesn't work for Linq-to-Database entities.</param>
/// <param name="parameters">A array from ParameterExpressions.</param>
/// <param name="resultType">Type of the result. If not specified, it will be generated dynamically.</param>
/// <param name="expression">The expression.</param>
/// <param name="parsingConfig">The Configuration for the parsing.</param>
/// <param name="values">An object array that contains zero or more objects which are used as replacement values.</param>
/// <returns>The generated <see cref="LambdaExpression"/></returns>
[PublicAPI]
public static LambdaExpression ParseLambda(bool createParameterCtor, [NotNull] ParameterExpression[] parameters, [CanBeNull] Type resultType, string expression, ParsingConfig parsingConfig, params object[] values)
public static LambdaExpression ParseLambda([CanBeNull] ParsingConfig parsingConfig, bool createParameterCtor, [NotNull] ParameterExpression[] parameters, [CanBeNull] Type resultType, [NotNull] string expression, params object[] values)
{
Check.NotNull(parameters, nameof(parameters));
Check.Condition(parameters, p => p.Count(x => x == null) == 0, nameof(parameters));
Expand Down
Loading