Skip to content

Commit

Permalink
Linq support for the specific case of string.ToLower().IsOneOf() and …
Browse files Browse the repository at this point in the history
…similar patterns chaining operators off of ToLower/Upper
  • Loading branch information
jeremydmiller committed Jan 13, 2025
1 parent 98540de commit 6d5d934
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 5 deletions.
7 changes: 7 additions & 0 deletions src/LinqTests/Acceptance/where_clauses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Threading.Tasks;
using LinqTests.Acceptance.Support;
using Marten;
using Xunit.Abstractions;

namespace LinqTests.Acceptance;
Expand Down Expand Up @@ -172,6 +173,12 @@ static where_clauses()
@where(x => x.String.ToLower() == "red");
@where(x => x.String.ToUpper() == "RED");

@where(x => x.String.ToLower().IsOneOf("red", "green"));
@where(x => x.String.ToLowerInvariant().IsOneOf("red", "green"));

@where(x => x.String.ToUpper().IsOneOf("RED", "GREEN"));
@where(x => x.String.ToUpperInvariant().IsOneOf("RED", "GREEN"));

@where(x => x.PaddedString.Trim() == "red");

}
Expand Down
8 changes: 5 additions & 3 deletions src/LinqTests/Operators/is_one_of_operator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
using System.Linq;
using System.Linq.Expressions;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Marten;
using Marten.Testing.Documents;
using Marten.Testing.Harness;
using Microsoft.FSharp.Core;
using Shouldly;
using Xunit.Abstractions;

namespace LinqTests.Operators;

public class is_one_of_operator: IntegrationContext
{
private readonly ITestOutputHelper _output;

public static TheoryData<Func<int[], Expression<Func<Target, bool>>>> SupportedIsOneOfWithIntArray =
new()
Expand Down Expand Up @@ -126,8 +129,6 @@ public class is_one_of_operator: IntegrationContext
validGuids => x => !x.FSharpGuidOption.In(validGuids)
};



[Theory]
[MemberData(nameof(SupportedIsOneOfWithIntArray))]
public void can_query_against_integers(Func<int[], Expression<Func<Target, bool>>> isOneOf) =>
Expand Down Expand Up @@ -307,8 +308,9 @@ Func<Target, T> select



public is_one_of_operator(DefaultStoreFixture fixture): base(fixture)
public is_one_of_operator(DefaultStoreFixture fixture, ITestOutputHelper output): base(fixture)
{
_output = output;
StoreOptions(_ =>
{
//_.Logger(new ConsoleMartenLogger());
Expand Down
9 changes: 7 additions & 2 deletions src/LinqTests/playing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
using Marten;
using Marten.Testing.Documents;
using Marten.Testing.Harness;
using Xunit.Abstractions;

namespace LinqTests;

public class playing : IntegrationContext
{
public playing(DefaultStoreFixture fixture) : base(fixture)
private readonly ITestOutputHelper _output;

public playing(DefaultStoreFixture fixture, ITestOutputHelper output) : base(fixture)
{
_output = output;
}

[Fact]
public async Task try_method_parsing()
{
var data = await theSession.Query<Target>().Where(x => x.String.EqualsIgnoreCase("something")).ToListAsync();
theSession.Logger = new TestOutputMartenLogger(_output);
var data = await theSession.Query<Target>().Where(x => x.String.ToLower().IsOneOf("red", "blue")).ToListAsync();
}
}
8 changes: 8 additions & 0 deletions src/Marten/Linq/Members/DuplicatedField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ public IQueryableMember FindMember(MemberInfo member)
{
RawLocator = $"upper({RawLocator})", TypedLocator = $"upper({RawLocator})"
},
nameof(string.ToLowerInvariant) => new StringMember(this, Casing.Default, member)
{
RawLocator = $"lower({RawLocator})", TypedLocator = $"lower({RawLocator})"
},
nameof(string.ToUpperInvariant) => new StringMember(this, Casing.Default, member)
{
RawLocator = $"upper({RawLocator})", TypedLocator = $"upper({RawLocator})"
},
_ => throw new BadLinqExpressionException($"Marten does not (yet) support the method {member.Name} in duplicated field querying")
};
}
Expand Down
9 changes: 9 additions & 0 deletions src/Marten/Linq/Members/StringMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public StringMember(IQueryableMember parent, Casing casing, MemberInfo member):
{
TypedLocator = RawLocator;
_lowerLocator = $"lower({RawLocator})";
MemberType = typeof(string);
}

public override IQueryableMember FindMember(MemberInfo member)
Expand All @@ -36,6 +37,14 @@ public override IQueryableMember FindMember(MemberInfo member)
{
RawLocator = $"upper({RawLocator})", TypedLocator = $"upper({RawLocator})"
},
nameof(string.ToLowerInvariant) => new StringMember(this, Casing.Default, member)
{
RawLocator = $"lower({RawLocator})", TypedLocator = $"lower({RawLocator})"
},
nameof(string.ToUpperInvariant) => new StringMember(this, Casing.Default, member)
{
RawLocator = $"upper({RawLocator})", TypedLocator = $"upper({RawLocator})"
},
nameof(string.Trim) => new StringMember(this, Casing.Default, member)
{
RawLocator = $"trim({RawLocator})", TypedLocator = $"trim({RawLocator})"
Expand Down
9 changes: 9 additions & 0 deletions src/Marten/Linq/Parsing/MemberFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
Members.Insert(0, LinqConstants.ArrayLength);
}

// This is fugly!
if (node.Method.Name.IsOneOf([
nameof(String.ToLower), nameof(String.ToUpper), nameof(String.ToLowerInvariant),
nameof(String.ToUpperInvariant)
]))
{
Members.Insert(0, node.Method);
}

return base.VisitMethodCall(node);
}

Expand Down

0 comments on commit 6d5d934

Please sign in to comment.