使用共享条件高效查询数据



我有多组数据,它们来自实体框架代码优先上下文(SQL CE(。有一个GUI显示每个查询集中的记录数,在更改某些设置条件(例如日期(时,所有集合都需要重新计算其"计数"值。

虽然每个集合的查询在某些方面略有不同,但它们中的大多数在某些方面共享共同的条件。一个简单的例子:

RelevantCustomers = People.Where(P=>P.Transactions.Where(T=>T.Date>SelectedDate).Count>0 && P.Type=="Customer")
RelevantSuppliers = People.Where(P=>P.Transactions.Where(T=>T.Date>SelectedDate).Count>0 && P.Type=="Supplier")

因此,这些要求很高的查询已经足够多了,每次用户更改某些条件(例如SelectedDate(时,都需要很长时间才能重新计算每组中的记录数。

我意识到,部分原因是需要查询,例如,每次都要查询交易,以检查RelevantCustomers和RelevantSuppliers的相同条件。

所以我的问题是,考虑到这些集合共享共同的"基本条件",这些条件依赖于相同的数据集,有没有更有效的方法可以计算这些集合?

我在想这样的自定义泛型类:

QueryGroup<People>(P=>P.Transactions.Where(T=>T.Date>SelectedDate).Count>0)
{
new Query<People>("Customers", P=>P.Type=="Customer"),
new Query<People>("Suppliers", P=>P.Type=="Supplier")
}

我可以很好地构建它,但我发现它基本上对效率没有影响,因为它仍然需要为每组重复"共享条件"。

我也尝试过先将基本条件数据作为静态"ToList(("取出,但这会在运行到导航实体(即People.Addresses未加载(时引发问题。

在效率方面,有什么我不知道的方法吗?

提前感谢!

试试这样的方法:将"相似"的值合并到更少的查询中,然后将结果分离。此外,使用Any()而不是Count()进行存在性检查。您的更新尝试进行了一部分,但仍将导致2次数据库命中。此外,在查询时,它有助于确保您是针对索引字段进行查询的,并且这些索引使用数字ID而不是字符串会更高效。(例如,对于"客户"one_answers"供应商",TypeID分别为1和2(标准化的值更适合索引,并导致更小的记录,而代价是额外的详细查询。

var types = new string[] {"Customer", "Supplier"};
var people = People.Where(p => types.Contains(p.Type)
&& p.Transactions.Any(t => t.Date > selectedDate)).ToList();
var relevantCustomers = people.Where(p => p.Type == "Customer").ToList();
var relevantSuppliers = people.Where(p => p.Type == "Supplier").ToList();

这只会导致对数据库的一次命中,并且Any应该比获取整个计数更高效。我们在事后从内存集中分离出客户和供应商。这里需要注意的是,任何访问客户和供应商交易等详细信息的尝试都会导致延迟加载,因为我们并不急于加载它们。如果您需要完整的实体图,那么一定要.Include((相关的详细信息,或者对从第一个查询中提取的数据更有选择性。即,选择具有适用详细信息的匿名类型,而不仅仅是实体。

最新更新