有两个IN参数的Lambda表达式到只有一个IN参数的Lambda表达式

本文关键字:Lambda 表达式 参数 IN 有一个 两个 | 更新日期: 2023-09-27 18:09:49

我有一个扩展方法,它有以下签名:

public static class GenericSeeder
{
    public static void Seed<TSeed, TEntity>(this DbContext context, IEnumerable<TSeed> seeds, Expression<Func<TEntity, TSeed, bool>> predicate)
    {
        // code that I'm looking for goes here
    }
}

为了更好地理解该方法的作用,下面是该方法的使用方法:

context.Seed<SeedClass, EntityClass>(seeds, (entity, seed) => entity.Name == seed.OtherProperty);

所以基本上,我使用谓词来检查是否已经应用了种子。然而,为了进行检查,我必须使用Linq to Entities中的Where或FirstOrDefault,它接受以下参数:

Expression<Func<TEntity, bool>> predicate

所以我的lambda表达式是2个IN参数(TSeed, TEntity)和1个OUT参数(bool)的函数。我需要迭代提供的TSeed对象集合,并且对于每个对象,使用该对象作为我的lambda表达式的参数,以生成LINQ 2实体lambda表达式,该表达式具有1个IN参数(TEntity)和1个OUT参数(bool)。

是否有办法做lambda表达式/func的部分调用,以获得另一个lambda表达式/func?

有两个IN参数的Lambda表达式到只有一个IN参数的Lambda表达式

通过使用LINQKit允许以一种将表达式转换为其他表达式的方式调用表达式,您的方法的实现变得相当简单:

public static IQueryable<TEntity> Seed<TSeed, TEntity>(
    this DbContext context,
    IEnumerable<TSeed> seeds,
    Expression<Func<TEntity, TSeed, bool>> predicate)
{
    return context.Set<TEntity>()
            .AsExpandable()
            .Where(entity => seeds.Any(seed => predicate.Invoke(entity, seed)));
}

我不知道你在做什么,但这就是你如何在c#中做部分应用程序:

Func<int,bool, string> twoInFunc= (int a, bool b) => a.ToString() + b.ToString();
int number = 7;
Func<bool, string> oneInFunc= (bool b) => twoInFunc(number,b);

我已经设法创建自己的解决方案。然而,我确实使用了臭名昭著的LinqKit扩展库和它的AsExpandable()扩展方法。

LinqKit可以在这里找到:NuGet链接

这就是Linq 2实体的实现:

public static void Seed<TSeed, TEntity>(this DbContext context, IEnumerable<TSeed> seeds, Expression<Func<TEntity, TSeed, bool>> predicate)
            where TEntity : class
            where TSeed : class
        {
            foreach (TSeed seed in seeds)
            {
                Expression<Func<TEntity, bool>> matchExpression = (entity) => predicate.Invoke(entity, seed);
                TEntity existing = context.Set<TEntity>().AsExpandable().FirstOrDefault(matchExpression);
            // Rest of code is omitted as it is not related to the original question.
            // The query above is properly executed by Linq 2 Entities.
            }
        }