标签: linq-expressions

如何创建NotStartsWith表达式树

我正在使用jqGrid向用户显示一些数据.jqGrid具有搜索功能,可以进行字符串比较,如Equals,NotEquals,Contains,StartsWith,NotStartsWith等.

当我使用时,StartsWith我得到有效的结果(看起来像这样):

Expression condition = Expression.Call(memberAccess,
                typeof(string).GetMethod("StartsWith"),
                Expression.Constant(value));
Run Code Online (Sandbox Code Playgroud)

由于DoesNotStartWith不存在,我创建了它:

public static bool NotStartsWith(this string s, string value)
{
    return !s.StartsWith(value);
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,我可以创建一个字符串并像这样调用此方法:

string myStr = "Hello World";
bool startsWith = myStr.NotStartsWith("Hello"); // false
Run Code Online (Sandbox Code Playgroud)

所以现在我可以像这样创建/调用表达式:

Expression condition = Expression.Call(memberAccess,
                typeof(string).GetMethod("NotStartsWith"),
                Expression.Constant(value));
Run Code Online (Sandbox Code Playgroud)

但是我收到了一个ArgumentNullException was unhandled by user code: Value cannot be null. Parameter name: method错误.

有谁知道为什么这不起作用或更好的方法来解决这个问题?

c# extension-methods linq-expressions

1
推荐指数
1
解决办法
425
查看次数

使用带有Queryable.Select的Expression.Call,其类型仅在运行时已知

我试图从一个IEnumerable集合中选择一个列,该列在运行时只有我知道的类型.我能想到使用它的唯一方法是使用LINQ表达式来构建动态调用Queryable.Select.但是,我在确定实现此目的的正确语法时遇到了很多麻烦.

我是如何在编译时知道我需要的所有事情的幸福世界中做到这一点的一个例子,我的代码看起来像这样:

' Create an IEnumerable(Of String)
Dim strings = { "one", "two", "three" }

' Produce a collection with elements {3,3,5}
Dim stringLengths = strings.Select(Function(x) x.Length)
Run Code Online (Sandbox Code Playgroud)

不幸的是,实际上我不知道我拥有的集合是类型String,还是我想要选择的属性Length.我所拥有的是IEnumerable一系列项目,以及PropertyInfo我想要选择的列,它为我提供了所需的所有类型信息.

就表达式而言,我已经能够创建一个LINQ表达式,我相信它将代表我通常会传递给选择的lambda(假设我尝试使用String和String.Length执行上面的相同操作)

' pi is the PropertyInfo containing the Length property I am trying to select.
' pi.DeclaringType is String and pi.Name is Length
Dim targetItem = Expression.Parameter(pi.DeclaringType, "x")
Dim targetProperty = Expression.Property(targetItem, pi.Name)

' Produces the lambda<Function(x) x.Length>
Dim selectLambda …
Run Code Online (Sandbox Code Playgroud)

.net vb.net reflection iqueryable linq-expressions

1
推荐指数
1
解决办法
1455
查看次数

如何将多个Linq表达式的结果合并为一个表达式?

我有一个Linq表达式列表,List<Expression>其中每个表达式类型(表达式将返回的类型)是ItemItem[].

我正在尝试编写一些代码,将提到的集合作为输入参数,并生成一个Linq表达式,它将返回一个列表(或数组)的项目(Item[]).

这是一个抽象的例子:

public static string[] GetStrings()
{
    return new[]
        {
            "first",
            "second",
            "third"
        };
}

public static string GetString()
{
    return "single1";
}

private void SOExample()
{
    var expressions = new List<Expression>
    {
        Expression.Call(GetType().GetMethod("GetString")),
        Expression.Call(GetType().GetMethod("GetStrings")), 
        Expression.Call(GetType().GetMethod("GetString")),
        Expression.Call(GetType().GetMethod("GetStrings"))
    };

    // some magic code here
    var combined = SomeMagicHere(expressions);
}


private Expression SomeMagicHere(List<Expression> expressions)
{
    foreach (var expression in expressions)
    {
        if (expression.Type.IsArray)
        {
            // Use array's elements
        } 
        else
        {
            // Use …
Run Code Online (Sandbox Code Playgroud)

c# linq lambda expression linq-expressions

1
推荐指数
1
解决办法
1292
查看次数

Linq表达式 - 无效参数

public class EcImageWrapper
{

    //etc...

    public IQueryable<EcFieldWrapper> ListOfFields
    {
        get
        {
            //logic here

            return this.listOfFields.AsQueryable();
        }
    }

    public EcFieldWrapper FindBy(Expression<Func<EcFieldWrapper, int, bool>> predicate)
    {
        return this.ListOfFields.Where(predicate).SingleOrDefault();
    }

    public EcFieldWrapper FindByName(string fieldName)
    {
        return this.FindBy(x => x.Name.ToUpper() == fieldName.ToUpper());
        //error here, wanting 3 arguments
        //which makes sense as the above Expression has 3
        //but i don't know how to get around this
    }
Run Code Online (Sandbox Code Playgroud)

由于某种原因,表达式>要求我使用3个参数,在过去我只使用2作为有问题的实例.但是,现在我想在这个实例中对一个集合进行查找.

我收到以下错误:

Delegate 'System.Func<MSDORCaptureUE.Wrappers.EcFieldWrapper,int,bool>' does not take 1 arguments
The best overloaded method match for 'CaptureUE.Wrappers.EcImageWrapper.FindBy(System.Linq.Expressions.Expression<System.Func<CaptureUE.Wrappers.EcFieldWrapper,int,bool>>)' has some …
Run Code Online (Sandbox Code Playgroud)

c# linq lambda func linq-expressions

1
推荐指数
1
解决办法
1730
查看次数

隐式类型局部变量必须初始化

我正在进行列排序,但出现编译时错误:

public static class Helper
{
    public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
    {
        if (colName != null && searchText != null)
    {
        var parameter = Expression.Parameter(typeof(T), "m");
        var propertyExpression = Expression.Property(parameter, colName);
        System.Linq.Expressions.ConstantExpression searchExpression = null;
        System.Reflection.MethodInfo containsMethod = null;
        switch (colName)
        {
            case "Title":
            case "Publisher":
            case "ToUser":
            case "CategoryName":
            case "StatusName":
            case "GroupName":
            case "FileSize":
                searchExpression = Expression.Constant(searchText);
                containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
                break;
            case "PublishDate":
                searchExpression = Expression.Constant(DateTime.ParseExact(searchText,"dd/MM/yyyy",null));
                containsMethod = typeof(string).GetMethod("Equals", …
Run Code Online (Sandbox Code Playgroud)

linq linq-expressions

1
推荐指数
1
解决办法
4456
查看次数

从表达式增加值

我想写一个闭包并增加它的值,但我无法做到.这是我的代码

        int i = 0;
        Expression<Func<bool>> closurExpression = () =>
                                                  {
                                                      i++;
                                                      return i != 0;
                                                  };
Run Code Online (Sandbox Code Playgroud)

但我得到多个错误A lambda expression with a statement body cannot be converted to an expression treeAn expression tree may not contain an assignment operator等等.是否可以不使用Mono.Cecil等外部工具?


对于这个问题:我为什么要求它.我想写一个简单的包装器(用于Func<T,T> at least计算调用计数的签名.例如:

Wrapper<int> wrapper = () => 5;
for(int i = 0; i < 10; i++)
   wrapper();
int calls = wrapper.Calls; // 10;
Run Code Online (Sandbox Code Playgroud)

我的第一个认识是:

class FunctionWithCounter<T, TResult>
{
    private readonly Func<T, TResult> function;
    public …
Run Code Online (Sandbox Code Playgroud)

.net c# reflection code-generation linq-expressions

1
推荐指数
1
解决办法
1173
查看次数

C#如何在一个循环中组合一些Linq表达式

我想结合一些Linq表达式,所以我从下面的文章中提供帮助:

http://www.c-sharpcorner.com/uploadfile/04fe4a/predicate-combinators-in-linq/http://thanhhh.blogspot.com/2011/10/linq-to-entities-predicatebuilder-and.html

我有一个像这样的通用列表:

List<long> lstPA = new List<long>() { 2, 3 }; // the numbers can be added or removed
Run Code Online (Sandbox Code Playgroud)

如果我在代码下使用合并我的linq表达式,我从db获得正确的结果(记录)(我使用Entity Framework 4.0):

var exp1 = Predicate.FalseExpression<posts>();            
exp1 = exp1.Or(x => x.post_author == 2);
exp1 = exp1.Or(x => x.post_author == 3);
Run Code Online (Sandbox Code Playgroud)

但是当我在foreach循环中组合linq表达式时这样:

var exp1 = Predicate.FalseExpression<posts>();
foreach (long id in lstPA)
{
    exp1 = exp1.Or(x => x.post_author == id);
}
Run Code Online (Sandbox Code Playgroud)

我无法从db获得正确的结果(记录).

什么是两个代码块之间的差异以及如何解决这个问题(我必须使用foreach循环)?

c# linq loops linq-expressions combiners

1
推荐指数
1
解决办法
708
查看次数

如何在不转换C#中的Expression.Convert的情况下获取Nullable值(字段)的表达式?

我在形成动态查询表达式期间处理Nullable类型的scanario.这些表达式将从任何SQL表中获取过滤数据(使用EF与Code First类连接).

我有正常的对象(例如,托运操作几个属性以及Nullable属性).

我的表达形式很顺利,直到我遇到一些Nullable类型.在这些无用之处,我得到了

没有为类型'System.Nullable`1 [System.Single]'和'System.Single'定义二元运算符NotEqual.

为了删除此异常,我正在使用关于在不同线程上发布的转换的所有appraoches.

在Expression树中调用lambda表达式

尝试使用表达式树过滤Nullable类型

这些都是生成带有"Convert"字样的表达式(即Convert(someValue)),结果我总是有表达式

t=>(t.Consignment.Id = 45000 && t.Consignment.someProperty>=45 Or t.Consignment.Weight! = Convert(5000)).
Run Code Online (Sandbox Code Playgroud)

当然我需要整个上面的表达式没有"转换".因为这个"转换"不会相应地从表中获取数据.

任何帮助将不胜感激!还应该做什么?我已经知道转换,但是这使得整个表达式无用,因为它不会因为不必要的"转换"而投影记录

添加

   Expression NotEqual<T>(Expression PropertyType, ConstantExpression a_Constant, ParameterExpression parameter)
   {
    if(IsNullableType(Property.Type) &&!IsNullableType(a_Constant.Type))
    {
      var converted = a_Constant.Type != Property.Type ?  (Expression)Expression.Convert(a_Constant, Property.Type): (Expression)a_Constant;

     // here above statement returns (Convert(50000)) and all I want (50000), but i tried all combinitions from Expression in order to form this constant as expression, it always throws exception what I mentioned originally.

     var body = …
Run Code Online (Sandbox Code Playgroud)

c# lambda expression-trees linq-expressions

1
推荐指数
1
解决办法
3334
查看次数

System.Linq.Expressions.Expression.CanReduce 属性是什么意思?

文档及其名称暗示,可以推断对于可以进一步分解为更小的表达式的所有表达式,该属性的值CanReduce必须设置为 true,反之亦然。

但经过仔细观察,这个推论似乎并不在所有情况下都成立。以 为例LambdaExpression,它肯定是一个复合单元。但是LambdaExpression直接从Expression类派生的类不会覆盖该CanReduce属性。该类将属性Expression定义CanReduce为 virtual 并具有返回 的实现false,因此意味着 lambda 表达式不可进一步简化,但事实并非如此。

那么这个属性的真正意义是什么?

linq custom-linq-providers linq-expressions

1
推荐指数
1
解决办法
386
查看次数

创建一个空表达式 &lt;Func&gt;

我正在使用存储库模式开发 .NET Core WebApi 项目,但在为特定情况实现解决方案时遇到问题:

这是我的 Controller 方法,我在其中传递一个名为 name 的变量,我将使用该变量为 LINQ 查询创建表达式

public async Task<ActionResult<ActivityDto>> GetPaginated(int page, int size, string name)
{
    var entities = await _activityService.GetPaginatedActivitiesAsync(page, size, name);

    if (!entities.Any())
        return NotFound();

    return new ObjectResult(entities) { StatusCode = StatusCodes.Status200OK };
}
Run Code Online (Sandbox Code Playgroud)

我的服务层的方法中也有这段代码,我用它来创建特定的表达式,然后调用我的存储库方法来执行特定的查询。

Expression<Func<Activity, bool>> filter = u => u.Name.Equals(name);
var entities = await _activityRepository.GetPaginatedAsync(page, size, filter);
Run Code Online (Sandbox Code Playgroud)

这是我的存储库中的行,我在其中执行查询,该查询根据输入名称返回所有记录。

await _context.Set<TEntity>().Where(filter).ToListAsync();
Run Code Online (Sandbox Code Playgroud)

当我将某个字符串传递给控制器​​中的 name 变量时,所有代码都可以正常工作。问题是我应该检查用户是否为名称字段输入了任何字符串,如果没有则返回所有记录。所以我的问题是:有没有办法创建类似空表达式的东西,然后由 LINQ 查询执行?

c# linq-expressions entity-framework-core asp.net-core-webapi

1
推荐指数
1
解决办法
1684
查看次数