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
5 changes: 3 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ steps:

# Build tests and run tests for net452 and netcoreapp2.1 (with coverage)
- script: |
dotnet test ./test/System.Linq.Dynamic.Core.Tests/System.Linq.Dynamic.Core.Tests.csproj --configuration Debug --framework net452
dotnet test ./test/System.Linq.Dynamic.Core.Tests/System.Linq.Dynamic.Core.Tests.csproj --configuration Debug --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
dotnet build ./test/System.Linq.Dynamic.Core.Tests/System.Linq.Dynamic.Core.Tests.csproj --configuration Debug
dotnet test ./test/System.Linq.Dynamic.Core.Tests/System.Linq.Dynamic.Core.Tests.csproj --no-build --configuration Debug --framework net452
dotnet test ./test/System.Linq.Dynamic.Core.Tests/System.Linq.Dynamic.Core.Tests.csproj --no-build --configuration Debug --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
displayName: 'Build tests and run tests for net452 and netcoreapp2.1 (with coverage)'

# End SonarScanner
Expand Down
18 changes: 12 additions & 6 deletions src/System.Linq.Dynamic.Core/DefaultQueryableAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public bool SupportsLinqToObjects(IQueryable query, IQueryProvider provider = nu
Check.NotNull(query, nameof(query));
provider = provider ?? query.Provider;

Type baseType = provider.GetType().GetTypeInfo().BaseType;
Type providerType = provider.GetType();
Type baseType = providerType.GetTypeInfo().BaseType;
#if NET35
bool isLinqToObjects = baseType.FullName.Contains("EnumerableQuery");
#else
Expand All @@ -24,13 +25,18 @@ public bool SupportsLinqToObjects(IQueryable query, IQueryProvider provider = nu
if (!isLinqToObjects)
{
// Support for https://github.com/StefH/QueryInterceptor.Core, version 1.0.1 and up
if (baseType.Name == "QueryTranslatorProvider")
if (providerType.Name.StartsWith("QueryTranslatorProvider"))
{
try
{
PropertyInfo property = baseType.GetProperty("OriginalProvider");
IQueryProvider originalProvider = property.GetValue(provider, null) as IQueryProvider;
return originalProvider != null && SupportsLinqToObjects(query, originalProvider);
PropertyInfo property = providerType.GetProperty("OriginalProvider");
if (property != null)
{
IQueryProvider originalProvider = property.GetValue(provider, null) as IQueryProvider;
return originalProvider != null && SupportsLinqToObjects(query, originalProvider);
}

return SupportsLinqToObjects(query);
}
catch
{
Expand All @@ -39,7 +45,7 @@ public bool SupportsLinqToObjects(IQueryable query, IQueryProvider provider = nu
}

// Support for https://github.com/scottksmith95/LINQKit ExpandableQuery
if (provider.GetType().GetTypeInfo().Name.StartsWith("ExpandableQuery"))
if (providerType.Name.StartsWith("ExpandableQuery"))
{
try
{
Expand Down
181 changes: 100 additions & 81 deletions src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ public void DynamicExpressionParser_ParseLambda_UseParameterizedNamesInDynamicQu
// Assert
dynamic constantExpression = ((MemberExpression)(expression.Body as BinaryExpression).Right).Expression as ConstantExpression;
dynamic wrappedObj = constantExpression.Value;
string value = wrappedObj.Value;

var propertyInfo = wrappedObj.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
string value = propertyInfo.GetValue(wrappedObj) as string;

Check.That(value).IsEqualTo("x");
}
Expand Down
4 changes: 2 additions & 2 deletions test/System.Linq.Dynamic.Core.Tests/EntitiesTests.Count.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ public void Entities_Count_Predicate()
const string search = "a";

//Arrange
var blog1 = new Blog { Name = "blog a", BlogId = 1000 };
var blog2 = new Blog { Name = "blog b", BlogId = 3000 };
var blog1 = new Blog { Name = "blog a", BlogId = 1000, Created = DateTime.Now };
var blog2 = new Blog { Name = "blog b", BlogId = 3000, Created = DateTime.Now };
_context.Blogs.Add(blog1);
_context.Blogs.Add(blog2);
_context.SaveChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public async Task Entities_CountAsync_Predicate_Args()
const string search = "a";

//Arrange
var blog1 = new Blog { Name = "blog a", BlogId = 1000 };
var blog2 = new Blog { Name = "blog b", BlogId = 3000 };
var blog1 = new Blog { Name = "blog a", BlogId = 1000, Created = DateTime.Now };
var blog2 = new Blog { Name = "blog b", BlogId = 3000, Created = DateTime.Now };
_context.Blogs.Add(blog1);
_context.Blogs.Add(blog2);
_context.SaveChanges();
Expand Down
20 changes: 10 additions & 10 deletions test/System.Linq.Dynamic.Core.Tests/EntitiesTests.Select.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections;
using System.Linq.Dynamic.Core.Exceptions;
using System.Linq.Dynamic.Core.Tests.Helpers.Entities;
using MongoDB.Bson;
using Newtonsoft.Json;
#if EFCORE
using Microsoft.EntityFrameworkCore;
#else
Expand All @@ -16,21 +16,21 @@ public partial class EntitiesTests : IDisposable
[Fact]
public void Entities_Select_SingleColumn_NullCoalescing()
{
//Arrange
var blog1 = new Blog { BlogId = 1000, Name = "Blog1", NullableInt = null };
var blog2 = new Blog { BlogId = 2000, Name = "Blog2", NullableInt = 5 };
//A rrange
var blog1 = new Blog { BlogId = 1000, Name = "Blog1", Created = DateTime.Now, NullableInt = null };
var blog2 = new Blog { BlogId = 2000, Name = "Blog2", Created = DateTime.Now, NullableInt = 5 };
_context.Blogs.Add(blog1);
_context.Blogs.Add(blog2);
_context.SaveChanges();

var expected1 = _context.Blogs.Select(x => (int?)(x.NullableInt ?? 10)).ToArray();
var expected2 = _context.Blogs.Select(x => (int?)(x.NullableInt ?? 9 + x.BlogId)).ToArray();

//Act
// Act
var test1 = _context.Blogs.Select<int?>("NullableInt ?? 10").ToArray();
var test2 = _context.Blogs.Select<int?>("NullableInt ?? 9 + BlogId").ToArray();

//Assert
// Assert
Assert.Equal(expected1, test1);
Assert.Equal(expected2, test2);
}
Expand All @@ -56,16 +56,16 @@ public void Entities_Select_EmptyObject()
ParsingConfig config = ParsingConfig.Default;
config.EvaluateGroupByAtDatabase = true;

//Arrange
// Arrange
PopulateTestData(5, 0);

var expected = _context.Blogs.Select(x => new {}).ToList();

//Act
// Act
var test = _context.Blogs.GroupBy(config, "BlogId", "new()").Select<object>("new()").ToList();

//Assert
Assert.Equal(expected.ToJson(), test.ToJson());
// Assert
Assert.Equal(JsonConvert.SerializeObject(expected), JsonConvert.SerializeObject(test));
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion test/System.Linq.Dynamic.Core.Tests/EntitiesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private void PopulateTestData(int blogCount = 25, int postCount = 10)
{
for (int i = 0; i < blogCount; i++)
{
var blog = new Blog { Name = "Blog" + (i + 1), BlogId = 1000 + i };
var blog = new Blog { Name = "Blog" + (i + 1), BlogId = 1000 + i, Created = DateTime.Now.AddDays(-Rnd.Next(0, 100)) };

_context.Blogs.Add(blog);

Expand Down
79 changes: 39 additions & 40 deletions test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Newtonsoft.Json.Linq;
using Xunit;
using NFluent;
using MongoDB.Bson;

namespace System.Linq.Dynamic.Core.Tests
{
Expand Down Expand Up @@ -44,7 +43,7 @@ public class TestObjectIdClass
{
public int Id { get; set; }

public ObjectId ObjectId { get; set; }
public long ObjectId { get; set; }
}

[Fact]
Expand Down Expand Up @@ -996,50 +995,50 @@ public void ExpressionTests_Indexer_Issue57()
Assert.Equal(expected, result);
}

[Fact]
public void ExpressionTests_IComparable_GreaterThan()
{
// Assign
const string id = "111111111111111111111111";
var queryable = new[] { new TestObjectIdClass { Id = 1, ObjectId = ObjectId.Parse(id) }, new TestObjectIdClass { Id = 2, ObjectId = ObjectId.Parse("221111111111111111111111") } }.AsQueryable();

// Act
var result = queryable.Where(x => x.ObjectId > ObjectId.Parse(id)).ToArray();
var dynamicResult = queryable.Where("it.ObjectId > @0", ObjectId.Parse(id)).ToArray();
// [Fact]
// public void ExpressionTests_IComparable_GreaterThan()
// {
// // Assign
// const string id = "111111111111111111111111";
// var queryable = new[] { new TestObjectIdClass { Id = 1, ObjectId = id }, new TestObjectIdClass { Id = 2, ObjectId = "221111111111111111111111" } }.AsQueryable();

// Assert
Check.That(dynamicResult).ContainsExactly(result);
}
// // Act
// var result = queryable.Where(x => x.ObjectId > id).ToArray();
// var dynamicResult = queryable.Where("it.ObjectId > @0", id).ToArray();

[Fact]
public void ExpressionTests_IEquatable_Equal()
{
// Assign
const string id = "111111111111111111111111";
var queryable = new[] { new TestObjectIdClass { Id = 1, ObjectId = ObjectId.Parse(id) }, new TestObjectIdClass { Id = 2, ObjectId = ObjectId.Parse("221111111111111111111111") } }.AsQueryable();
// // Assert
// Check.That(dynamicResult).ContainsExactly(result);
// }

// Act
var result = queryable.First(x => x.ObjectId == ObjectId.Parse(id));
var dynamicResult = queryable.First("it.ObjectId == @0", ObjectId.Parse(id));
// [Fact]
// public void ExpressionTests_IEquatable_Equal()
// {
// // Assign
// const string id = "111111111111111111111111";
// var queryable = new[] { new TestObjectIdClass { Id = 1, ObjectId = id }, new TestObjectIdClass { Id = 2, ObjectId = ObjectId.Parse("221111111111111111111111") } }.AsQueryable();

// Assert
Check.That(dynamicResult.Id).Equals(result.Id);
}
// // Act
// var result = queryable.First(x => x.ObjectId == ObjectId.Parse(id));
// var dynamicResult = queryable.First("it.ObjectId == @0", ObjectId.Parse(id));

[Fact]
public void ExpressionTests_IEquatable_NotEqual()
{
// Assign
const string id = "111111111111111111111111";
var queryable = new[] { new TestObjectIdClass { Id = 1, ObjectId = ObjectId.Parse(id) }, new TestObjectIdClass { Id = 2, ObjectId = ObjectId.Parse("221111111111111111111111") } }.AsQueryable();
// // Assert
// Check.That(dynamicResult.Id).Equals(result.Id);
// }

// Act
var result = queryable.First(x => x.ObjectId != ObjectId.Parse(id));
var dynamicResult = queryable.First("it.ObjectId != @0", ObjectId.Parse(id));

// Assert
Check.That(dynamicResult.Id).Equals(result.Id);
}
// [Fact]
// public void ExpressionTests_IEquatable_NotEqual()
// {
// // Assign
// const string id = "111111111111111111111111";
// var queryable = new[] { new TestObjectIdClass { Id = 1, ObjectId = ObjectId.Parse(id) }, new TestObjectIdClass { Id = 2, ObjectId = ObjectId.Parse("221111111111111111111111") } }.AsQueryable();

// // Act
// var result = queryable.First(x => x.ObjectId != ObjectId.Parse(id));
// var dynamicResult = queryable.First("it.ObjectId != @0", ObjectId.Parse(id));

// // Assert
// Check.That(dynamicResult.Id).Equals(result.Id);
// }

[Fact]
public void ExpressionTests_LogicalAndOr()
Expand Down
13 changes: 10 additions & 3 deletions test/System.Linq.Dynamic.Core.Tests/QueryableTests.Cast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,33 @@ public void Cast_Explicit()
{
{ "Id", new JValue(9) },
{ "Name", new JValue("Test 9") },
{ "Items", new JArray(new JValue(1), new JValue("two")) }
{ "Items", new JArray(new JValue(1), new JValue("one")) }
};

var test2 = new JObject
{
{ "Id", new JValue(10) },
{ "Name", new JValue("Test 10") },
{ "Items", new JArray(new JValue(1), new JValue("two")) }
{ "Items", new JArray(new JValue(2), new JValue("two")) }
};

var queryable = new[] { test1, test2 }.AsQueryable();

// Act
var result = queryable.Select(x => new { Id = (int)x["Id"], Name = (string)x["Name"] }).OrderBy(x => x.Id).ToArray();
var result = queryable.Select(x => new { Id = (int)x["Id"], Name = (string)x["Name"], Item0 = (int) x["Items"].Values().ToArray()[0], Item1 = (string)x["Items"].Values().ToArray()[1] }).OrderBy(x => x.Id).ToArray();
var resultDynamic = queryable.Select("new (int(Id) as Id, string(Name) as Name, int(Items[0]) as Item0, string(Items[1]) as Item1)").OrderBy("Id").ToDynamicArray();

// Assert
Check.That(resultDynamic.Count()).Equals(result.Count());
Check.That(resultDynamic[0].Id).Equals(result[0].Id);
Check.That(resultDynamic[0].Name).Equals(result[0].Name);
Check.That(resultDynamic[0].Item0).Equals(result[0].Item0);
Check.That(resultDynamic[0].Item1).Equals(result[0].Item1);

Check.That(resultDynamic[1].Id).Equals(result[1].Id);
Check.That(resultDynamic[1].Name).Equals(result[1].Name);
Check.That(resultDynamic[1].Item0).Equals(result[1].Item0);
Check.That(resultDynamic[1].Item1).Equals(result[1].Item1);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
<AssemblyName>System.Linq.Dynamic.Core.Tests</AssemblyName>
<DebugType>full</DebugType>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>System.Linq.Dynamic.Core.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AssemblyOriginatorKeyFile>../../src/System.Linq.Dynamic.Core/System.Linq.Dynamic.Core.snk</AssemblyOriginatorKeyFile>
<ProjectGuid>{912FBF24-3CAE-4A50-B5EA-E525B9FAEC80}</ProjectGuid>
</PropertyGroup>

Expand All @@ -21,20 +20,19 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />
<PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="4.0.0" />
<PackageReference Include="xunit.runner.console" Version="2.4.0">
<PackageReference Include="xunit.runner.console" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0">
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Linq.PropertyTranslator.Core" Version="1.0.4" />
<PackageReference Include="QueryInterceptor.Core" Version="1.0.6" />
<PackageReference Include="Linq.PropertyTranslator.Core" Version="1.0.5" />
<PackageReference Include="QueryInterceptor.Core" Version="1.0.7" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="NFluent" Version="2.1.1" />
<PackageReference Include="Moq" Version="4.10.0" />
Expand Down
Binary file not shown.