使用 .net 函数过滤实体框架信息

Posted

技术标签:

【中文标题】使用 .net 函数过滤实体框架信息【英文标题】:Using .net functions to filter Entity Framework information 【发布时间】:2013-06-13 02:39:13 【问题描述】:

我有不同的函数,它们具有数学方法,而其他一些函数具有字符串处理方法,例如我拥有的一些函数是:IntegralUtils.RegionalArea(double x, double y) 和 StringUtils.RabinKarp(string x)。

我正在使用 Entity Framework 4.1,当我想在 Linq 查询的过滤器部分中使用这些函数时,出现了一个错误,即没有这样的等效函数:

var res = from item  in Items
          where IntegralUtils.RegionalArea(item.X, item.Y)
          select item;

我的快速解决方案是在不过滤的情况下获取所有项目,并在 foreach 循环中迭代项目并使用 if 表达式进行过滤,我认为这当然不是最好的解决方案。

但我的问题是我是否可以使用自定义 CLR 函数制作实体框架来接受这种 Linq 查询,或者我如何制作类似的东西?

提前致谢

【问题讨论】:

【参考方案1】:

正如@Robert McKee 所指出的,您不能将自己的函数添加到查询中,因为 Entity-Framework 会将您的 C# 查询转换为 SQL,然后在服务器上执行它。由于它不知道如何翻译您的 RegionalArea 方法,因此它失败了。

您可以按照 Robert 的建议进行操作 - 将 SQL 中的所有数据带到您的进程中(使用 ToList() 方法),然后过滤 .NET 集合。这会起作用,但如果数据库中有很多项目,并且查询最终只返回其中的几个,则可能会很慢。

我不会将您的 RegionArea 方法转移到数据库中,那样很快就会变得非常混乱。相反,如果性能是一个问题,我会在将它们添加到数据库时预先计算每个项目的区域区域 - 只需添加一个 Item.RegionalArea 属性并在构建项目时用正确的值填充它。然后查询变得微不足道。

注意:是的,我知道与之前的解决方案相比,我选择了一些非规范化。我认为这种非规范化是值得的——在代码和数据库之间拆分逻辑会花费更多。

【讨论】:

【参考方案2】:

这会很慢,因为它必须从数据库中检索整个表,然后它会过滤,但这是你想要的:

var res=Items.ToList().Where(i=>IntegralUtils.RegionalArea(i.X,i.Y));

如果您更喜欢查询语法,我相信这也可以:

var res=from item  in Items.ToList()
          where IntegralUtils.RegionalArea(item.X, item.Y)
          select item;

【讨论】:

谢谢罗伯特,我正在考虑这个问题,这可能是一个选择,但我正在阅读谓词构建器,我不知道这是否有助于加快速度,或者最好的方法是你提到的那个? 除非您在 SQL Server 上有 IntegralUtils 库,否则谓词构建器不会帮助您提高性能。 这可能会对您在 SQL Server msdn.microsoft.com/en-us/library/dd456847%28VS.100%29.aspx987654321@上的函数有所帮助

以上是关于使用 .net 函数过滤实体框架信息的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Asp.net MVC 和实体框架中分页时应用过滤器?

实体框架 DbContext 过滤的计数查询使用变量非常慢

在实体框架中使用 bindingSource 的过滤器

实体框架过滤器索引

实体框架过滤器“表达式<Func<T, bool>>”

实体框架6过滤子对象