1

我有一个场景,我需要能够动态查询实体,使用它的相关数据并从数据库、实体及其相关数据返回。

在此处输入图像描述

因此,例如,我会编写一个如下所示的查询来查询联系人:

context.Contacts.Where(c.Forename == "Alex" &&
c.MetaData.Any(meta => meta.ItemName == "Email" && meta.ItemValue == "alex@myemail.com"))

但是,我不仅要返回联系人表条目,还要返回联系人的地址以及联系人的所有元数据。

我已经研究了 Include() 语句以及 DataLoadOptions.LoadWith() 选项,但是这两个选项都效率低下,因为它们是基于每个实体进行查询的。因此,如果我的查询匹配 200 个实体,则地址将有 200 个查询,元数据将有 200 个查询。所以这不会有任何用处。

或者,我可以在 Linq 查询上构造一个 .Select() 语句,将联系人、地址和元数据记录组合在一起。但是,对于具有 2 个地址和 10 个元数据项的单个实体 - 这将导致 20 条记录以平面格式返回。这对于单个实体来说是可怕的——但想象一下,在 200 个匹配的实体中呢?将 4000 条记录解析为 20 个实体...... Yuk。

所以,我有点卡住了。如果我完全在 DB 层,我将构建一个查询,将 Id 转储到一个临时表中,然后加入每个表并将它们一起返回,然后在域逻辑中,我将获取 IMultipleResults 并从那。

但是,我的问题是我必须将用户驱动的查询转换为 linq 语法(使用表达式)并以这种方式查询。T-SQL 绝不是动态的,无法让我做任何我需要做的事情。

我可以查询每组数据,但这意味着对数据库进行三次点击,而我只需要缩小一次结果集并为此提取相关数据。如果获取 Contact.ContactIds 的初始查询需要一段时间,我不希望复合用户体验并使其花费 3 倍的时间。

关于如何克服这种令人讨厌的要求组合的任何想法?

4

1 回答 1

0

我已经找到了这个链接:在没有 Skip() 的 LINQ 查询中使用 Take() 会导致效率低下的行为

在 LINQ 查询中使用 LoadWith() 和 Take() 似乎存在错误。我的测试和分析使用了没有 Skip() 的 Take() 语句。幸运的是,在我们的实现中,我们正在分页,所以我们已经一起使用了 Skip() 和 Take(),所以我们不受这个 bug 的影响。

查看在 SqlProfiler 中执行的 SQL - 仅执行一条语句,返回一个合并数据的大型记录集(如我在问题中所述)。然而,与我的手动解析相比,Linq 似乎处理得更好,并最终提供了可读性更高的代码。

希望这可以帮助。

于 2013-09-10T08:54:16.497 回答