自定义扩展功能以实现;在;在c#(LINQ-2-实体)中

自定义扩展功能以实现;在;在c#(LINQ-2-实体)中,c#,entity-framework,linq,extension-methods,C#,Entity Framework,Linq,Extension Methods,例如: .Contains(…)在LINQ2实体中受支持,并转换为“in”SQL表达式 我想重写此查询: var foundExntities = myDbContext.MyEntityes.Where(o => new List<int> {111, 222, 333).Contains(o.ID)).ToList() 如何在(…)扩展函数中编写通信和自定义 如何在(…)扩展函数中编写通信和自定义 如果不编写一个完整的查询提供程序,它可以通过识别自定义扩展方法并相应地转换

例如:

.Contains(…)在LINQ2实体中受支持,并转换为“in”SQL表达式

我想重写此查询:

var foundExntities = myDbContext.MyEntityes.Where(o => new List<int> {111, 222, 333).Contains(o.ID)).ToList()
如何在(…)扩展函数中编写通信和自定义

如何在(…)扩展函数中编写通信和自定义

如果不编写一个完整的查询提供程序,它可以通过识别自定义扩展方法并相应地转换它们来转换表达式树(类似于
AsExpandable()
implementation)

不过,您可以创建一个自定义的
IQueryable
扩展方法,但该方法只能与LINQ方法语法一起使用,并且只能与根可查询运算符一起使用:

public static partial class QueryableExtensions
{
    public static IQueryable<T> WhereIn<T, V>(this IQueryable<T> source, Expression<Func<T, V>> valueSelector, params V[] values)
    {
        var condition = Expression.Call(
            typeof(Enumerable), "Contains", new[] { typeof(V) },
            Expression.Constant(values), valueSelector.Body);
        var predicate = Expression.Lambda<Func<T, bool>>(condition, valueSelector.Parameters);
        return source.Where(predicate);
    }
}

我建议你不要。在
int
上定义扩展方法是非常混乱的,因为这些方法会泄漏到无法使用的上下文中(编写它们以便在任何地方都可以使用似乎不值得)。除此之外,我不认为您可以——该方法需要被EF表达式树解析器识别,并且我认为它们没有扩展点。(虽然我对EF本身还不太熟悉,无法确定。)我想您可以包装
IQueryable
实现,但即使这样似乎也远比它的价值麻烦。虽然可以使用
params int[]
声明整数参数的可变数量(请参阅),我反对像EF中那样创建自定义聚合方法。它可能会引发这样的问题,例如
LINQ to Entities不识别该方法
,因为自定义方法有时不会直接转换为SQL查询。我只想将著名的EF(LINQ-2-SQL)表达式提取到这样的宏函数中。这个函数只会扩展我的查询树。“你的查询树”仍然需要使用与其他所有方法相同的解析器方法进行解析,你不能更改这些方法,这就是问题所在。您可以重写表达式树,以便现有的EF解析器能够识别它,但是您没有执行此操作的钩子——
。Where()
的定义不在您的控制之下。(除非你写它,以及所有其他使用谓词的方法,但这似乎不可取。)你为什么要这样做?Thanx很多Ivan!嗨@Ivan Stoev,如果我错了,请纠正我,但是看起来T和V必须是相同的类型,那么为什么要指定其中的2个呢?它难道不能像公共静态IQueryable一样(这个IQueryable源、表达式值选择器、参数t[]值)?Thanks@LeonardoSpina
V
T
的属性类型,由
表达式值选择器
表示。所以在这个例子中,
T
MyEntity
V
int
,我们检查
int ID
属性。它类似于有两种类型-源、键和键选择器。
public static partial class QueryableExtensions
{
    public static IQueryable<T> WhereIn<T, V>(this IQueryable<T> source, Expression<Func<T, V>> valueSelector, params V[] values)
    {
        var condition = Expression.Call(
            typeof(Enumerable), "Contains", new[] { typeof(V) },
            Expression.Constant(values), valueSelector.Body);
        var predicate = Expression.Lambda<Func<T, bool>>(condition, valueSelector.Parameters);
        return source.Where(predicate);
    }
}
var foundEntities = myDbContext.MyEntityes.WhereIn(o => o.ID, 111, 222, 33).ToList();