0

我正在使用 LINQ to Entity in Razor。我有这样的事情:

@foreach(Org o in Model) {
    @foreach(User u in o.Users.Where(x => x.Active==true) ) {
       <span> @u.FirstName </span>
    }
}

当我查看 SQL Server Profiler 时,查询有两个主要的低效率:

  1. 它返回用户表中的所有列
  2. 它返回用户表中的所有行,而不仅仅是那些 Active==true 的行。

当然它可以正常工作,但我的印象是 LINQ 比这更聪明,并且会向 SQL 服务器发送更具体的查询。

问题:我可以让 LINQ 传递 WHERE 子句 (Active==true) 并且只自动获取 FirstName 列吗?

ps 除非严格相关,否则我对视图中的 LINQ 是否是好的做法不太感兴趣——例如,视图的优化是否与编译的代码不同?

这是我的控制器代码:

public ActionResult Index()
{
    xyz_Entities db = new xyz_Entities();
    return PartialView(db.Orgs);
}

更新 - 许多道歉,这实际上是一个嵌套循环,可能很重要。

4

3 回答 3

5

它返回用户表中的所有列

确实如此——Linq 不知道你打算使用这些数据——所以它会返回所有的列。

它返回用户表中的所有行,而不仅仅是那些 Active==true 的行。

我猜这是因为Model通过调用ToList或实现控制器中的所有记录AsEnumerable

为了避免这些,我会在控制器而不是视图中进行查询,并将结果作为模型或ViewData字典的一部分传递。您可以尝试将查询缩减为:

var names = Model.Users.Where(x => x.Active==true)
                       .Select(u => u.FirstName)
                       .ToList();
ViewData["Names"] = names;
于 2013-02-21T14:53:49.610 回答
2

您尚未显示填充模型的位置,但这就是数据访问发生的位置,也是您从数据库中检索所有用户的原因。

当您到达此视图时,您已经填充了您的Users集合,因此您只需将 LINQ to Objects 与您的内存集合一起使用。

您将需要更改填充模型的数据访问代码,以在数据库查询级别应用过滤器。

于 2013-02-21T14:52:39.340 回答
1

它可能会拉出所有行,因为您正在调用ToListToArray因为声明的类型Model.UsersIEnumerable<>而不是IQueryable<>. 对扩展方法的调用被编译器重写为像普通静态方法一样被调用,并且编译器使用声明的类型来确定IEnumerable<>vs IQueryable<>

修复过滤问题后,您可以使用Select扩展方法准确告诉 EF 您希望查询返回哪些列。

于 2013-02-21T14:58:18.787 回答