Skip to content

Commit

Permalink
adding (client side) support for Contains operator in query. CR: Andrew
Browse files Browse the repository at this point in the history
  • Loading branch information
maumar committed Dec 29, 2014
1 parent 7305ce3 commit a2e689d
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/EntityFramework.Core/Query/AsyncLinqOperatorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ public virtual MethodInfo Where
private static readonly MethodInfo _all = GetMethod("All", 1);
private static readonly MethodInfo _cast = GetMethod("Cast");
private static readonly MethodInfo _count = GetMethod("Count");
private static readonly MethodInfo _contains = GetMethod("Contains", 1);
private static readonly MethodInfo _defaultIfEmpty = GetMethod("DefaultIfEmpty");
private static readonly MethodInfo _defaultIfEmptyArg = GetMethod("DefaultIfEmpty", 1);
private static readonly MethodInfo _distinct = GetMethod("Distinct");
Expand Down Expand Up @@ -290,6 +291,11 @@ public virtual MethodInfo Count
get { return _count; }
}

public virtual MethodInfo Contains
{
get { return _contains; }
}

public virtual MethodInfo DefaultIfEmpty
{
get { return _defaultIfEmpty; }
Expand Down
1 change: 1 addition & 0 deletions src/EntityFramework.Core/Query/ILinqOperatorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public interface ILinqOperatorProvider
MethodInfo All { get; }
MethodInfo Cast { get; }
MethodInfo Count { get; }
MethodInfo Contains { get; }
MethodInfo DefaultIfEmpty { get; }
MethodInfo DefaultIfEmptyArg { get; }
MethodInfo Distinct { get; }
Expand Down
6 changes: 6 additions & 0 deletions src/EntityFramework.Core/Query/LinqOperatorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ public virtual MethodInfo Where
private static readonly MethodInfo _all = GetMethod("All", 1);
private static readonly MethodInfo _cast = GetMethod("Cast");
private static readonly MethodInfo _count = GetMethod("Count");
private static readonly MethodInfo _contains = GetMethod("Contains", 1);
private static readonly MethodInfo _defaultIfEmpty = GetMethod("DefaultIfEmpty");
private static readonly MethodInfo _defaultIfEmptyArg = GetMethod("DefaultIfEmpty", 1);
private static readonly MethodInfo _distinct = GetMethod("Distinct");
Expand All @@ -240,6 +241,11 @@ public virtual MethodInfo Count
get { return _count; }
}

public virtual MethodInfo Contains
{
get { return _contains; }
}

public virtual MethodInfo DefaultIfEmpty
{
get { return _defaultIfEmpty; }
Expand Down
18 changes: 18 additions & 0 deletions src/EntityFramework.Core/Query/ResultOperatorHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class ResultOperatorHandler : IResultOperatorHandler
{ typeof(AverageResultOperator), (v, _, __) => HandleAverage(v) },
{ typeof(CastResultOperator), (v, r, __) => HandleCast(v, (CastResultOperator)r) },
{ typeof(CountResultOperator), (v, _, __) => HandleCount(v) },
{ typeof(ContainsResultOperator), (v, r, q) => HandleContains(v, (ContainsResultOperator)r, q) },
{ typeof(DefaultIfEmptyResultOperator), (v, r, q) => HandleDefaultIfEmpty(v, (DefaultIfEmptyResultOperator)r, q) },
{ typeof(DistinctResultOperator), (v, _, __) => HandleDistinct(v) },
{ typeof(FirstResultOperator), (v, r, __) => HandleFirst(v, (ChoiceResultOperatorBase)r) },
Expand Down Expand Up @@ -112,6 +113,23 @@ private static Expression HandleCount(EntityQueryModelVisitor entityQueryModelVi
entityQueryModelVisitor.Expression);
}

private static Expression HandleContains(
EntityQueryModelVisitor entityQueryModelVisitor,
ContainsResultOperator containsResultOperator,
QueryModel queryModel)
{
var item = entityQueryModelVisitor
.ReplaceClauseReferences(
containsResultOperator.Item,
queryModel.MainFromClause);

return CallWithPossibleCancellationToken(
entityQueryModelVisitor.LinqOperatorProvider.Contains
.MakeGenericMethod(entityQueryModelVisitor.StreamedSequenceInfo.ResultItemType),
entityQueryModelVisitor.Expression,
item);
}

private static Expression HandleDefaultIfEmpty(
EntityQueryModelVisitor entityQueryModelVisitor,
DefaultIfEmptyResultOperator defaultIfEmptyResultOperator,
Expand Down
22 changes: 22 additions & 0 deletions test/EntityFramework.Core.FunctionalTests/AsyncQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,28 @@ public virtual async Task String_EndsWith_MethodCall()
await AssertQuery<Customer>(cs => cs.Where(c => c.ContactName.EndsWith(LocalMethod2())));
}

[Fact]
public virtual async Task Contains_with_subquery()
{
await AssertQuery<Customer, Order>((cs, os) =>
cs.Where(c => os.Select(o => o.CustomerID).Contains(c.CustomerID)));
}

[Fact]
public virtual async Task Contains_with_local_collection()
{
string[] ids = new[] { "ABCDE", "ALFKI" };
await AssertQuery<Customer>(cs =>
cs.Where(c => ids.Contains(c.CustomerID)));
}

[Fact]
public virtual async Task Contains_top_level()
{
await AssertQuery<Customer>(cs =>
cs.Select(c => c.CustomerID).ContainsAsync("ALFKI"));
}

private static string LocalMethod1()
{
return "M";
Expand Down
22 changes: 22 additions & 0 deletions test/EntityFramework.Core.FunctionalTests/QueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,28 @@ public virtual void SelectMany_Joined_DefaultIfEmpty()
select new { c.ContactName, o });
}

[Fact]
public void Contains_with_subquery()
{
AssertQuery<Customer, Order>((cs, os) =>
cs.Where(c => os.Select(o => o.CustomerID).Contains(c.CustomerID)));
}

[Fact]
public void Contains_with_local_collection()
{
string[] ids = new[] { "ABCDE", "ALFKI" };
AssertQuery<Customer>(cs =>
cs.Where(c => ids.Contains(c.CustomerID)), stateEntryCount: 1);
}

[Fact]
public void Contains_top_level()
{
AssertQuery<Customer>(cs =>
cs.Select(c => c.CustomerID).Contains("ALFKI"));
}

protected NorthwindContext CreateContext()
{
return Fixture.CreateContext();
Expand Down

0 comments on commit a2e689d

Please sign in to comment.