C# linq中where子句对实体的扩展方法

C# linq中where子句对实体的扩展方法,c#,entity-framework,linq-to-entities,C#,Entity Framework,Linq To Entities,在LINQtoEntities中,我们需要一种类似“sql-like”的方法。我们已经实现了自己对IQueryable的扩展方法,因为contains方法不适用于我们,因为它不接受像“%a%b%”这样的模式 创建的代码是: private const char WildcardCharacter = '%'; public static IQueryable<TSource> WhereLike<TSource>(this IQueryable<TSource&g

在LINQtoEntities中,我们需要一种类似“sql-like”的方法。我们已经实现了自己对IQueryable的扩展方法,因为contains方法不适用于我们,因为它不接受像“%a%b%”这样的模式

创建的代码是:

private const char WildcardCharacter = '%';

public static IQueryable<TSource> WhereLike<TSource>(this IQueryable<TSource> _source, Expression<Func<TSource, string>> _valueSelector, string _textSearch)
{
    if (_valueSelector == null)
    {
        throw new ArgumentNullException("valueSelector");
    }

        return _source.Where(BuildLikeExpressionWithWildcards(_valueSelector, _textSearch));
}

private static Expression<Func<TSource, bool>> BuildLikeExpressionWithWildcards<TSource>(Expression<Func<TSource, string>> _valueSelector, string _textToSearch)
{
    var method = GetPatIndexMethod();

    var body = Expression.Call(method, Expression.Constant(WildcardCharacter + _textToSearch + WildcardCharacter), _valueSelector.Body);

    var parameter = _valueSelector.Parameters.Single();
    UnaryExpression expressionConvert = Expression.Convert(Expression.Constant(0), typeof(int?));
    return Expression.Lambda<Func<TSource, bool>> (Expression.GreaterThan(body, expressionConvert), parameter);
}

private static MethodInfo GetPatIndexMethod()
{
    var methodName = "PatIndex";

    Type stringType = typeof(SqlFunctions);
    return stringType.GetMethod(methodName);
}
问题是where子句中使用的方法必须返回bool结果,如果它与诸如“| |”之类的运算符一起使用,我不知道如何使我创建的代码返回bool并使代码在sqlserver中执行。我想我必须通过BuildLinqExpression方法将返回的表达式转换为bool,但我不知道该怎么做

总而言之!首先,是否可以在Linq中创建我们自己的extensiond方法,以便在SqlServer中执行代码的实体?如果可能的话,我该怎么做


谢谢您的帮助。

不,您无法教育EF处理自定义扩展方法,即使您有代码构建可用于EF的表达式

要么:

  • 直接在EF
    Where
    表达式中使用
    SqlFunctions
    方法
  • 使用
    ExpressionVisitor
    将多个表达式组合成一个复合(
    OrElse
    /
    /
    和also
    )表达式(请注意,这并不能帮助您获得所需的代码,但它可以让您使用这两个方法并对它们执行
    |
    ,不过看起来很复杂)
第一个更简单、更清楚。

回答如下:

他的代码:

允许您将扩展方法标记为
[Expandable]
,只要它返回的表达式适用于linq2entities,它就会用内部表达式替换函数调用。请注意,内联lambda会给出错误,因此我必须将它们声明为局部变量或静态变量,例如
IsCurrent
变量:

static Expression<Func<PropertyHistory, bool>> IsCurrent = (p) => p.Starts <= DateTime.Now;

[ExpandableMethod]
public static IQueryable<PropertyHistory> AsOf(this IQueryable<PropertyHistory> source)
{
  return source.Where(IsCurrent);
}

static Expression IsCurrent=(p)=>p.开始您尝试使用了吗?@dasblinkenlight SqlMethods不能在Linq to Entity中使用。如果我没有错的话,SqlMethods不能在Linq to Entities中使用,我已经尝试过并崩溃了。另一个用户报告了相同的@Marc对不起,我可能是指
SqlFunctions
——即您在bonnet@Marc而且:如果那是你自己的课,那么:你无能为力。可能只是编写SQL并通过EF将其向下推,而不是尝试编写LINQ。好的,感谢您的帮助,不直接使用SqlFunctions的原因是为了让代码尽可能干净。如果有人能提供帮助,我有一个相关但不同的问题:
static Expression<Func<PropertyHistory, bool>> IsCurrent = (p) => p.Starts <= DateTime.Now;

[ExpandableMethod]
public static IQueryable<PropertyHistory> AsOf(this IQueryable<PropertyHistory> source)
{
  return source.Where(IsCurrent);
}