Skip to content

Conversation

@boris612
Copy link
Contributor

I have made some changes in QueryableHelper class in order to enable use of LessThan, LessThanOrEqual, GreaterThan, and GreaterThanOrEqual on Strings and avoid the following runtime error: System.InvalidOperationException: The binary operator LessThan is not defined for the types 'System.String' and 'System.String'.

The workaround calls CompareTo methods (defined in Constants.cs), i.e.,
if (conditionOperator == ConditionOperators.LessThan) { if (member.Type == stringType) ret = Expression.LessThan(Expression.Call(member, Constants.CompareToMethod, constant), Expression.Constant(0)); else ret = Expression.LessThan(member, constant); }

@dlebee
Copy link
Member

dlebee commented Nov 27, 2019

I will look at it, are those methods compatible with EF and EF Core?

@boris612
Copy link
Contributor Author

Brief test on InMemory database passes:

 [TestMethod]
        public void TestLessAndGreaterThan()
        {
            var context = GetCoreContext(nameof(TestWhereAnd)); //EF Core     
          //or new BlogContext(testConnectionString);     in EF
            SeedForTests(context);

            var query = context.Authors.Query(q => q.LessThan("FirstName", "Mario"));            
            var first = query.FirstOrDefault();
            Assert.AreEqual(first?.FirstName, "David");

            query = context.Authors.Query(q => q.GreaterThan("FirstName", "Mario"));
            first = query.FirstOrDefault();
            Assert.AreEqual(first?.FirstName, "Some");
        }

@dlebee
Copy link
Member

dlebee commented Nov 27, 2019

Ok very cool i'll take a look very soon :)

@dlebee dlebee merged commit a1b3a3b into PoweredSoft:master Nov 27, 2019
@dlebee
Copy link
Member

dlebee commented Nov 27, 2019

@boris612 I am pushing up a pre-release for you to try it should be 1.1.10-beta.

Let me know if everything works well, then I will make it a non-prereleased version.

@boris612
Copy link
Contributor Author

@dlebee I have tested operators against a real database, and they work fine.

However, it would be useful to add a note to the documentation that case sensitive settings cannot be used with these operators, and that results depends on source type. If the underlying source is an objects collection, then the comparison is case sensitive. If the underlying source is a database, then it depends how the database is configured.
The reason for this behavior is the fact that EF cannot efficiently translate string comparison query if case sensitivity settings are used. For example, the following code

ctx.Authors.Where(a => string.Compare(a.FirstName, "David", StringComparison.Ordinal) < 0).Count();

will cause execution of the following query

SELECT FirstName FROM Authors 

and then retrieve all data in memory and count those that satisfies the condition.

Contrary, code

ctx.Authors.Where(a => a.FirstName.CompareTo("David") < 0).Count();

translates to

SELECT COUNT(*) FROM Authors WHERE FirstName < 'David'

@dlebee
Copy link
Member

dlebee commented Nov 28, 2019

Yes the case sensitiveness are only for in memory operations, by default they are not activated.

@dlebee
Copy link
Member

dlebee commented Nov 28, 2019

Releasing 1.1.10 now, I did my tests too yesterday, thank you for the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants