咨询区
- Techy:
我有下面的一段 asp.net core LINQ 代码。
List<UserSearchResult> results = await db.ApplicationUsers.Where(u => u.Name.StartsWith(name) && !u.Deleted && u.AppearInSearch)
.OrderByDescending(u => u.Verified)
.ThenBy(u => u.DateAdded) // Added to prevent duplication of results in different pages
.Skip(page * recordsInPage)
.Take(recordsInPage)
.Select(u => new UserSearchResult()
{
Name = u.Name,
Verified = u.Verified,
PhotoURL = u.PhotoURL,
UserID = u.Id,
Subdomain = u.Subdomain
}).ToListAsync();
我发现它把linq转成下面这样了。
SELECT [t].[Name], [t].[Verified], [t].[PhotoURL], [t].[Id], [t].[Subdomain]
FROM (
SELECT [u0].*
FROM [AspNetUsers] [u0]
WHERE (([u0].[Name] LIKE @__name_0 + N'%'
AND CHARINDEX(@__name_0, [u0].[Name]) = 1)
OR @__name_0 = NULL)
AND [u0].[Deleted] = 0
AND [u0].[AppearInSearch] = 1
ORDER BY [u0].[Verified] DESC, [u0].[DateAdded]
OFFSET @__p_1 ROWS FETCH NEXT @__p_2 ROWS ONLY
) [t]
我很疑惑的是:为什么会多出下面这一段? 仅仅用一个 like 不就可以了吗?
(CHARINDEX(@__name_0, [u0].[Name]) = 1)) OR (@__name_0 = N''))
回答区
- Ivan Stoev:
EF Core 中的sql转换规则仍然还有很多不足之处,离完美还差的很远,关于 StartsWith,EndsWith 和 Contains 这些方法的sql转换,在内部或者外部讨论中都被多次提起,比如:github:https://github.com/dotnet/efcore/issues/474 ,如果你想生成你想要的,当前有一个变通的方式,就是一部分 sql,一部分 linq ,参考下面的代码。
var results = await db.ApplicationUsers
//.Where(u => u.Name.StartsWith(name) && !u.Deleted && u.AppearInSearch)
.FromSql("select * from ApplicationUsers where Name like {0}", name + "%")
.Where(!u.Deleted && u.AppearInSearch)
.OrderByDescending(u => u.Verified)
.ThenBy(u => u.DateAdded) // Added to prevent duplication of results in different pages
.Skip(page * recordsInPage)
.Take(recordsInPage)
.Select(u => new UserSearchResult()
{
Name = u.Name,
Verified = u.Verified,
PhotoURL = u.PhotoURL,
UserID = u.Id,
Subdomain = u.Subdomain
}).ToListAsync();
上面的代码,我就用了 FromSql 做了这样的定制化。
- R.Titov:
Entity Framework 提供了一个类sql 的 EF.Functions.Like 几个方法,你可以把它拼在 Linq Expressions 中,比如下面的例子。
var likeExpression = name+"%";
... await db.ApplicationUsers.Where(u => EF.Functions.Like(u.Name,likeExpression)...
点评区
特斯拉最大的毛病就是太便宜,Entity Framework 最大的毛病就是封装的太狠,sql复杂起来后,原来便捷的sql生成就是此时最大的障碍!