I have a simple SQL statement:
select * from Employee
where LEFT(REPLACE(EmployeeName,'.',''),4) IN ('ABCE', 'BCDS', 'EDSC', 'XDSD', 'EFSE')
And I am trying to do this in Linq:
Employees.Where(x => new[] { "ABCE", "BCDS", "EDSC", "XDSD", "EFSE" }.Contains((x.EmployeeName.Replace(".", "").Substring(0, 4))));
but the SQL statement it generates is not efficient. The EmployeeName is updated everytime before comparing to the strings instead of just once:
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[EmployeeName] AS [EmployeeName],
[Extent1].[EmployeeTypeID] AS [EmployeeTypeID],
[Extent1].[Active] AS [Active]
FROM [dbo].[Employee] AS [Extent1]
WHERE (N'ABCE' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'BCDS' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'EDsC' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'XDSs' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'EFSE' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
How can I make the generated SQL look more like the original sql statement? Thanks
I only tested it with linqpad but i think this will generate a more efficient query.
var result = from record in Employee
let name = record.EmployeeName.Replace( ".", "" ).Substring( 0, 4 )
where new[] { "ABCE", "BCDS", [...] }.Contains( name )
select record;
This is strange, but I rewrote your query and generated sql statement was
WHERE (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4) IN (N'ABCE', N'BCDS', N'EDSC', N'XDSD', N'EFSE')) AND (SUBSTRING(REPLACE([Extent1].[Name], N'.', N'')
I guess that depends on used database and framework (in my case SQL Server 2008 and EF).
If you are using EF, you can force EF to use your sql statement
context.Set<Employee>().SqlQuery("select * from Employee where LEFT(REPLACE(EmployeeName,'.',''),4) IN ('ABCE', 'BCDS', 'EDSC', 'XDSD', 'EFSE')");
I think you can't (easily, at least) control such detail of the sql statements generation process.
But, if you are looking for the best possibile query, I would give a try to the LIKE
operator (by making use, in your LINQ query, of a serie of .StartsWith
conditions).
LIKE
can use sql indexes, which is probably not happening with SUBSTRING
and REPLACE
.
I think you are comparing a character array instead of a string. Try this
Employees.Where(x => new string[] { "ABCE", "BCDS", "EDSC", "XDSD", "EFSE" }
.Contains((x.EmployeeName.Replace(".", "").Substring(0, 4).ToString())));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.