gpt4 book ai didi

c# - 基于 Linq 的泛型替代 Predicate

转载 作者:太空狗 更新时间:2023-10-29 17:45:28 24 4
gpt4 key购买 nike

我有一个名为 ICatalog 的接口(interface)如下所示,其中每个 ICatalog有一个名称和一个方法,将根据 Predicate<Item> 返回项目功能。

public interface ICatalog
{
string Name { get; }
IEnumerable<Item> GetItems(Predicate<Item> predicate);
}

目录的特定实现可以链接到各种格式的目录,例如 XML 或 SQL 数据库。

对于 XML 目录,我最终将整个 XML 文件反序列化到内存中,因此使用谓词函数测试每个项目不会增加太多开销,因为它已经在内存中。

然而,对于 SQL 实现,我宁愿不将数据库的全部内容检索到内存中,然后使用谓词函数过滤项目。相反,我想找到一种方法以某种方式将谓词传递给 SQL 服务器,或者以某种方式将其转换为 SQL 查询。

这似乎是一个可以用 Linq 解决的问题,但我对它还很陌生。我的界面应该返回 IQueryable 吗?我现在不关心如何实际实现我的 ICatalog 的 SQL 版本。我只是想确保我的界面将来允许它。

最佳答案

Rob 已经指出了您可以如何执行此操作(尽管更经典的 LINQ 方法可能采用 Expression<Func<Item,bool>> ,并可能返回 IQueryable<IFamily> )。

好消息是,如果您想将谓词与 LINQ-to-Objects(对于您的 xml 场景)一起使用,您可以使用:

Predicate<Item> func = predicate.Compile();

或(对于其他签名):

Func<Item,bool> func = predicate.Compile();

并且您有一个委托(delegate) (func) 来测试您的对象。

但问题是,这是单元测试的噩梦 - 您只能真正集成测试它。

问题是您不能可靠地模拟(使用 LINQ-to-Objects)任何涉及复杂数据存储的东西;例如,以下内容在您的单元测试中可以正常工作,但对数据库“真正”不起作用:

var foo = GetItems(x => SomeMagicFunction(x.Name));

static bool SomeMagicFunction(string name) { return name.Length > 3; } // why not

问题是只有一些操作可以转换为 TSQL。 IQueryable<T> 也会遇到同样的问题- 例如,EF 和 LINQ-to-SQL 支持对查询的不同操作;甚至只是First()行为不同(EF 要求您首先明确对其进行排序,而 LINQ-to-SQL 则没有)。

总结一下:

  • 它可以工作
  • 但请仔细考虑是否要这样做;更经典的黑盒存储库/服务接口(interface)可能更易于测试

关于c# - 基于 Linq 的泛型替代 Predicate<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2783767/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com