nam*_*nam 3 c# linq-to-entities sql-server-2012 entity-framework-core asp.net-core-1.1
以下LINQ查询应该返回每个用户的登录次数:
控制器:
var lst = _context.LoginHistory.GroupBy(l => l.UserName).Select(lg => new { user_name = lg.Key, cnt = lg.Count() });
return View(lst.ToList());
Run Code Online (Sandbox Code Playgroud)
但是SQL Profiler of SQL Server 2012返回以下奇怪的查询:
SQL事件探查器输出:
SELECT [l].[LoginHistory], [l].[Hit_Count], [l].[LastLogin], [l].[UserName]
FROM [LoginHistory] AS [l]
ORDER BY [l].[UserName]
Run Code Online (Sandbox Code Playgroud)
型号:
public class LoginHistory
{
public int LoginHistoryId { get; set; }
public string UserName { get; set; }
public int Hit_Count { get; set; }
public DateTime LoginDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
注意:
Hit_Count在探查器输出查询中,因为它在这里不起作用- 我正在尝试的是显示每个用户的登录总数.而且,在SQL Profiler输出中,我期待类似于以下t-sql:预期[或类似的] SQL事件探查器输出:
SELECT username, COUNT(*)
FROM LoginHistory
GROUP BY username
Run Code Online (Sandbox Code Playgroud)
这次它并不是一个真正的错误(根据EF Core团队),但功能不完整(因为在EF6中它的工作方式与预期相同).您可以在EF核心路线图中看到它"记录" :
在我们说EF Core是EF的推荐版本之前我们认为我们需要的东西.在我们实现这些功能之前,EF Core将是许多应用程序的有效选项,特别是在诸如UWP和.NET Core等平台上,其中EF6.x不起作用,但对于许多应用程序而言,缺少这些功能将使EF6.xa成为更好的选择.
然后
GroupBy转换将LINQ GroupBy运算符的转换移动到数据库,而不是内存中.
所谓的客户评估(以前的EF版本中不存在的EF Core的一个特性)是所有邪恶的根源.它允许EF Core在内存中"成功"处理许多查询,从而引入性能问题(尽管根据定义它们应该产生正确的结果).
这就是为什么我建议总是打开EF Core Logging来监控你的查询真正发生了什么.例如,对于示例查询,您将看到以下警告:
The LINQ expression 'GroupBy([l].UserName, [l])' could not be translated and will be evaluated locally. To configure this warning use the DbContextOptionsBuilder.ConfigureWarnings API (event id 'RelationalEventId.QueryClientEvaluationWarning'). ConfigureWarnings can be used when overriding the DbContext.OnConfiguring method or using AddDbContext on the application service provider.
The LINQ expression 'GroupBy([l].UserName, [l])' could not be translated and will be evaluated locally. To configure this warning use the DbContextOptionsBuilder.ConfigureWarnings API (event id 'RelationalEventId.QueryClientEvaluationWarning'). ConfigureWarnings can be used when overriding the DbContext.OnConfiguring method or using AddDbContext on the application service provider.
The LINQ expression 'Count()' could not be translated and will be evaluated locally. To configure this warning use the DbContextOptionsBuilder.ConfigureWarnings API (event id 'RelationalEventId.QueryClientEvaluationWarning'). ConfigureWarnings can be used when overriding the DbContext.OnConfiguring method or using AddDbContext on the application service provider.
Run Code Online (Sandbox Code Playgroud)
您还可以通过在DbContext OnConfiguring覆盖中添加以下内容来关闭客户端评估:
optionsBuilder.ConfigureWarnings(bulder => bulder.Throw(RelationalEventId.QueryClientEvaluationWarning));
Run Code Online (Sandbox Code Playgroud)
但现在您将从该查询中简单地获取运行时异常.
如果这对您来说很重要,那么您可能属于应用程序类别,缺少这些功能将使EF6.xa成为更好的选择.