实体框架二级过滤器

问题描述 投票:0回答:1

我在表格中有以下列:

OrderId
CustomerId
TimeZoneOffset   <-- in minutes
DateOrderUTC     <-- This field is indexed
...
...
...

当用户过滤日期时,我需要考虑订单的时区。我知道,我可以只创建没有 UTC 的 DateOrder(在创建订单时使用它们的时区)。但这是给我的数据库。

这张表包含大约200万条记录。如果我使用下面的代码,它不会使用索引查找,因为它需要添加时区

return (from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
        where (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) >= startDate) && (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) <= endDate)
        select rec).Count();

所以,我的想法是为 startDate 添加 -1 天,为 endDate 添加 +1 天,以欺骗优化器使用索引。所以,代码看起来像这样:

startDate = startDate.AddDays(-1);
endDate = endDate.AddDays(1);
var vRecs = (from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
             where (rec.DateOrderUTC >= startDate) && (rec.DateOrderUTC <= endDate)
             select rec);
//I don't want to return the list first because it can be hundreds of thousands of records.
return ???;   //how to do another filter here before returning the Count?

有什么想法吗?

提前感谢您的帮助...

c# entity-framework
1个回答
0
投票

您可以添加另一个

where
子句,甚至可以将其组合在第二个查询中。

var qRec1 = from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
            where (rec.DateOrderUTC >= startDate) && (rec.DateOrderUTC <= endDate)
            select rec;

var qRec2 = from rec in qRec1
            where (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) >= startDate) && (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) <= endDate)
            select rec;

var count = qRec2.Count();

但是您应该真正使用单个查询并将 startDate/endDate 转换为 UTC,这样您就不会将列表达式包装在非 SARGable 表达式中,并且可以使用索引。

var qRec = from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
            where rec.DateOrderUTC >= DbFunctions.AddMinutes(startDate, -rec.TimeZoneOffset) 
               && rec.DateOrderUTC < DbFunctions.AddMinutes(endDate,-rec.TimeZoneOffset) 
            select rec;
© www.soinside.com 2019 - 2024. All rights reserved.