gpt4 book ai didi

c# - Func 的逻辑逆

转载 作者:太空狗 更新时间:2023-10-30 00:07:31 26 4
gpt4 key购买 nike

我的代码库中有一些相当复杂的 Entity Framework 查询,我决定将逻辑集中到模型中。基本上,想象一堆 Controller ,它们的表达式树中有大量查询和大量重复代码。所以我取出了部分表达式树并将它们移到模型中,以减少重复。

例如,假设我经常需要获取名为 Entity 的处于未删除状态的模型。在我的实体模型上,我有:

public static Func<Entity, bool> IsNotDeleted = e =>
e.Versions != null ?
e.Versions.OrderByDescending(v => v.VersionDate).FirstOrDefault() != null ?
e.Versions.OrderByDescending(v => v.VersionDate).First().ActivityType != VersionActivityType.Delete :
false :
false;

(这是较小的示例之一,大部分只是在尝试检查数据之前检查有效数据。)

使用它看起来像:

var entities = EntityRepository.Entities.Where(Entity.IsNotDeleted).Where(...

但是,我发现,虽然有时我想要未删除的记录,但其他时候我想要 已删除的记录。为此,有没有办法从消费代码中反转逻辑?概念上类似于此的东西(显然不起作用):

var entities = EntityRepository.Entities.Where(!Entity.IsDeleted).Where(...

我不想有两个 Func<>对象上的 s,一个用于 IsDeleted和一个 IsNotDeleted这几乎是相同的。 Func<>返回 bool ,当把它放在 .Where() 中时,是否有一种语法可以调用它的逆函数?条款?

最佳答案

考虑以下扩展方法。

public static class Functional
{
public static Func<T, bool> Not<T>(this Func<T, bool> f)
{
return x => !f(x);
}

public static Expression<Func<T, bool>> Not<T>(
this Expression<Func<T, bool>> f)
{
// 1. Break the lambda f apart into its parameters and body.
// 2. Wrap the body expression with a unary not expression (!).
// 3. Construct a new lambda with the modified body.
return Expression.Lambda<Func<T, bool>>(
Expression.Not(f.Body), f.Parameters);
}
}

Entity.IsDeleted.Not()Entity.IsNotDeleted()相同.

请注意,您可能希望使用 Expression<Func<T, bool>> - 不是 Func<T, bool> - 这样您的 lambda 逻辑就可以在数据库端而不是客户端使用。

你可以这样使用它:

Expression<Func<int, bool>> isNegative = x => x < 0;
Expression<Func<int, bool>> isNonNegative = isNegative.Not();

关于c# - Func<T, bool> 的逻辑逆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24316284/

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