SapientGuardian.EntityFrameworkCore.MySql
SapientGuardian.EntityFrameworkCore.MySql copied to clipboard
Bug when using StartsWith()
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', '%')
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.
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);
}
Suggested fix generates:
WHERE x.ColumnName LIKE ('%' @__parameter_0 '%')
which is not inline with StartWith.