SapientGuardian.EntityFrameworkCore.MySql icon indicating copy to clipboard operation
SapientGuardian.EntityFrameworkCore.MySql copied to clipboard

Bug when using StartsWith()

Open mguinness opened this issue 8 years ago • 3 comments

There appears to be a bug when using StartsWith() method in a LINQ query:

var customers = _ctx.Customers.Where(c => c.CustomerName.StartsWith("a")).ToList();

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONCAT('a', '%') '%')'

SELECT * FROM `Customers` AS `c` WHERE `c`.`CustomerName` LIKE ('%' CONCAT('a', '%') '%')

Should probably be output as

SELECT * FROM `Customers` AS `c` WHERE `c`.`CustomerName` LIKE CONCAT('a', '%')

mguinness avatar Nov 22 '16 06:11 mguinness

I can see why this is doing this straight away, it is doing a VisitLikeExpression and then VisitBinaryExpression. Should be an easy fix I'll have a look when I'm back at a computer.

eByte23 avatar Nov 22 '16 08:11 eByte23

After a quick look, it looks like something like this would fix this issue but its abit messy. This would be in MySQLQuerySqlGenerator.cs

protected override Expression VisitBinary(BinaryExpression expression)
		{
			if(expression.NodeType == ExpressionType.Add && expression.Type == typeof(string))
			{
                if (expression.Right.ToString().Contains("%"))
                {
                    Visit(expression.Left);
                    return expression;
                }
                else if (expression.Left.ToString().Contains("%"))
                {
                    Visit(expression.Right);
                    return expression;
                }

				Sql.Append("CONCAT(");
				Visit(expression.Left);
				Sql.Append(", ");
				Visit(expression.Right);
				Sql.Append(")");

				return expression;
			}

			return base.VisitBinary(expression);
		}

eByte23 avatar Nov 22 '16 10:11 eByte23

Suggested fix generates: WHERE x.ColumnName LIKE ('%' @__parameter_0 '%') which is not inline with StartWith.

vvdimov avatar Dec 31 '16 05:12 vvdimov