Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有两个IN参数的Lambda表达式到具有单个IN参数的Lambda表达式_C#_Linq_Generics_Lambda - Fatal编程技术网

C# 具有两个IN参数的Lambda表达式到具有单个IN参数的Lambda表达式

C# 具有两个IN参数的Lambda表达式到具有单个IN参数的Lambda表达式,c#,linq,generics,lambda,C#,Linq,Generics,Lambda,我的扩展方法具有以下签名: 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 l

我的扩展方法具有以下签名:

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
    }
}
公共静态类GenericSeeder
{
公共静态void Seed(此DbContext上下文、IEnumerable Seed、表达式谓词)
{
//我要找的代码在这里
}
}
为了更好地了解该方法的作用,以下是该方法的使用方法:

context.Seed<SeedClass, EntityClass>(seeds, (entity, seed) => entity.Name == seed.OtherProperty);
context.Seed(种子,(实体,种子)=>entity.Name==Seed.OtherProperty);
因此,基本上,我使用谓词来检查是否已经应用了种子。但是,为了进行检查,我必须使用Where或FirstOrDefault从Linq到实体,它将以下内容作为参数:

Expression<Func<TEntity, bool>> predicate
表达式谓词
所以我的lambda表达式是2个IN参数(TSeed,tenty)和1个OUT参数(bool)的函数。我需要遍历提供的TSeed对象集合,对于其中的每一个对象,使用该对象作为lambda表达式的参数,以生成具有1个IN参数(tenty)和1个OUT参数(bool)的linq2实体lambda表达式


有没有办法部分调用lambda expression/func以获得另一个lambda expression/func?

我不知道您在做什么,但这就是在c#中执行部分应用程序的方法:

Func twoInFunc=(inta,bool b)=>a.ToString()+b.ToString();
整数=7;
Func oneInFunc=(bool b)=>twoInFunc(number,b);

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

LinqKit可在此处找到:

这就是与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.
            }
        }
publicstaticvoidseed(此DbContext上下文、IEnumerable种子、表达式谓词)
地点:班级
在哪里上课
{
foreach(种子中的种子)
{
表达式匹配表达式=(实体)=>predicate.Invoke(实体,种子);
TEntity existing=context.Set().AsExpandable().FirstOrDefault(匹配表达式);
//代码的其余部分被省略,因为它与原始问题无关。
//上面的查询由Linq 2实体正确执行。
}
}

通过使用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)));
}
公共静态可读取种子(
在这种背景下,
无数的种子,
表达式(谓词)
{
返回context.Set()
.AsExpandable()
.Where(entity=>seed.Any(seed=>predicate.Invoke(entity,seed));
}

虽然我想我知道你想要什么,但我不是100%确定。您可以使用
(x,y)=>{x.Frob();return y==x;}
或类似的方法来执行多语句lambda(在我看来编译得很好,可能没有真正的编译器)。这将允许您在内部只使用一个属性,然后使用另一个属性。我不能保证除了linq to对象之外的任何linq提供程序都能够使用它(事实上,我希望可能不会)。谓词中的比较总是
==
?不幸的是,您的解决方案对我没有帮助,因为由于linq 2实体的要求,我需要表达式转换。如果我按照您的建议进行尝试,结果是:LINQ to实体中不支持LINQ表达式节点类型“Invoke”。这是将查询计算为每个种子的值。你不应该这么做。@Servy你能提供更好的解决方案吗?是的,我能提供更好的解决方案。@Servy你介意吗?:)虽然我不担心性能,因为这是一种只在迁移运行时才会调用的方法,但我确实有兴趣查看比这更好的方法:)对不起,虽然您的答案对特定场景有一个值(因此是向上投票),但对于我的场景,由于实现的其余部分,它并不是最优的。您可能在表达式到T-SQL的转换上节省了时间,但另一方面,我必须再次迭代查询结果,并为每个种子找到匹配的实体(因为您一次获取所有内容,如果使用太多种子,查询可能会变得非常大).@BarisaPuter如果您的方法接受适当的投影作为参数,您可以轻松地按种子值对实体进行分组,或者只需期望调用方根据输出对种子进行分组即可。无论采用哪种方式对值进行分组所花费的精力都不是特别大。如果你有很多种子,那么做大量的DB往返来获取它们是一个大问题。每次往返都会非常昂贵。
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)));
}