【问题标题】:Use Linq Any query or Expressions to build query for performance使用 Linq 任何查询或表达式来构建查询以提高性能
【发布时间】:2020-01-26 10:15:06
【问题描述】:

我们是我们项目中的实体框架。需要知道 .ANY() 和 Expressions 之间的性能影响以形成 Where 子句。

在下面的函数中,我使用了两种方法来获得结果:

方法 1 - 使用 ANY() 形成 Lambda 表达式查询 根据我的观察,使用 .Any() 不会在执行查询时添加 where 子句(在 sql profiler 中检查),EF 所做的是将所有匹配的内部连接记录存储在内存中,然后应用 .ANY() 中指定的条件

方法 2 - 表单表达式查询开始 使用表达式,我在 SQL 查询探查器中明确形成 where 子句和执行。检查相同,我能够看到 where 子句。 注意:为了形成表达式 where 子句,我正在做额外的循环和“CombinePredicates”。

现在,我的疑问是:

  1. 哪种方法可以提高性能。我需要和 Lambda 一起去吗 使用 .ANY() 还是表达式?

  2. 从 where 子句提高性能的正确方法是什么?

如果不是这两种方法建议我正确的方法

private bool GetClientNotifications(int clientId, IList<ClientNotification> clientNotifications)
{
IList<string> clientNotificationList = null;
var clientNotificationsExists = clientNotifications?.Select(x => new { x.Name, x.notificationId 
}).ToList();
if (clientNotificationsExists?.Count > 0)
{

    //**Approach 1 => Form Lamada  Query starts**
    notificationList = this._clientNotificationRepository?.FindBy(x => clientNotificationsExists.Any(x1 => x.notificationId == x1.notificationId && x.clientId == 
  clientId)).Select(x => x.Name).ToList();
    **//Form Lamada  Query Ends**

    //**Approach 2 =>Form Expression Query Starts**
    var filterExpressions = new List<Expression<Func<DbModel.ClientNotification, bool>>>();
    Expression<Func<DbModel.ClientNotification, bool>> predicate = null;
    foreach (var clientNotification in clientNotificationsExists)
    {
        predicate = a => a.clientId == clientId && a.notificationId == clientNotification .notificationId;
        filterExpressions.Add(predicate);
    }
    predicate = filterExpressions.CombinePredicates<DbModel.ClientNotification>(Expression.OrElse);
    clientNotificationList = this._clientNotificationRepository?.FindBy(predicate).Select(x => x.Name).ToList();
    //**Form Expression Query Ends**
}
return clientNotificationList;
  }

如果这些方法都不好,请建议我正确的方法。

【问题讨论】:

  • 还比较它生成的原始sql。还要检查您的数据库是否在任何情况下都正确索引,这将是最大的瓶颈
  • db 表索引正确。在这里,我需要知道从上述场景中提高性能的最佳方法

标签: c# mysql lambda entity-framework-6 expression


【解决方案1】:

我注意到两种方法中使用的 clientId 都用于与 clientNotificationsExists 相关联的条件,但与其对象没有实际关系,因此可以将此条件上移一级。这可能会带来微不足道的好处,因为如果没有重复的子句,整个 sql 会更小。

从所描述的行为来看,第一种方法过滤器没有被转换为 sql,因此它在客户端被解析,但是,如果它可以被转换,性能将是相似或相同的。

如果要生成 IN sql 子句,可以使用数组并在过滤器表达式中使用 Contains 方法。这可能会有所改善,但不要抱太大希望。

尝试以下方法:

private bool GetClientNotifications(int clientId, IList<ClientNotification> clientNotifications)
{
    IList<string> clientNotificationList = null;
    var clientNotificationsExists = clientNotifications?
        .Select(x => new { x.Name, x.notificationId }).ToList();
    if (clientNotificationsExists?.Count > 0)
    {
        var notificationIds = clientNotificationsExists.Select(x => x.notificationId).ToArray();
        clientNotificationList = this._clientNotificationRepository?
            .FindBy(x => x.clientId == clientId && notificationIds.Contains(x.notificationId));
    }
    return clientNotificationList;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多