linq如何构建where谓词

时间:2017-06-03 12:08:11

标签: c# linq linq-expressions

我想查询IEnumerable的形状。我有不同种类的形状,它们根据形状的类型以不同的方式与给定的坐标相关。

对于任何给定的坐标,我想找到它的相关形状。我想用Linq来做这件事。但是由于缺乏理解而陷入困境。一直在搜索和阅读几个小时,但我可以找到正确的单词,让我举一个我想要做的例子。下面是一些代码,希望能够显示我想要做的概念,但显然不起作用。必须有一种链接这些表达式的方法 - 我已经看过谓词构建器并且可能会使用它,但我想首先学习更多基础知识。 我如何使这项工作?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace LinqLearning
{
    public class Coordinate
    {
        public double X { get; set; }
        public double Y { get; set; }
    }
    public abstract class Bounded
    {
        public Coordinate TopRight { get; set; }
        public Coordinate BottomLeft { get; set; }
    }

    public class Shape1 : Bounded
    { }
    public class Shape2 : Bounded
    { }
    public class LinqExperiments
    {
        public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator)
        {
            Expression<Func<Bounded, Coordinate, bool>> Shape1NearCoordinate =
                (shape, coord) => shape.TopRight.Y > coord.Y &&
                                  shape.BottomLeft.Y < coord.Y &&
                                  shape.TopRight.X == coord.X;
            Expression<Func<Bounded, Coordinate, bool>> Shape2NearCoordinate =
                (shape, coord) => shape.TopRight.Y == coord.Y &&
                                  shape.TopRight.X < coord.X + 3 &&
                                  shape.TopRight.X > coord.X - 3;


            Expression<Func<IQueryable<Bounded>, Coordinate, bool>> predicate = (shapes, coord) => Shape1NearCoordinate || Shape2NearCoordinate;

            return shapesEnumerable.AsQueryable().Where(predicate);
        }
    }
}

2 个答案:

答案 0 :(得分:2)

我真的不明白你使用ExpressionIQueryable的原因。我认为这可以通过Func<Bounded, Coordinate, bool>来解决:

    public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator)
    {
        Func<Bounded, Coordinate, bool> Shape1NearCoordinate =
            (shape, coord) => shape.TopRight.Y > coord.Y &&
                              shape.BottomLeft.Y < coord.Y &&
                              shape.TopRight.X == coord.X;
        Func<Bounded, Coordinate, bool> Shape2NearCoordinate =
            (shape, coord) => shape.TopRight.Y == coord.Y &&
                              shape.TopRight.X < coord.X + 3 &&
                              shape.TopRight.X > coord.X - 3;
        Func<Bounded, Coordinate, bool> predicate = (shapes, coord) => Shape1NearCoordinate(shapes, coord) || Shape2NearCoordinate(shapes, coord);
        return shapesEnumerable.Where(x => predicate(x, locator));
    }

答案 1 :(得分:0)

为什么不坚持简单的简单功能?当不需要LambdaLinq Expressions时,无需使用它们。

static bool Shape1NearCoordinate(Bounded shape, Coordinate coord) {
    return shape.TopRight.Y > coord.Y &&
            shape.BottomLeft.Y < coord.Y &&
            shape.TopRight.X == coord.X;
}

static bool Shape2NearCoordinate(Bounded shape, Coordinate coord) {
    return shape.TopRight.Y == coord.Y &&
            shape.TopRight.X < coord.X + 3 &&
            shape.TopRight.X > coord.X - 3;
}

public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator) {
    return shapesEnumerable.Where(shape => Shape1NearCoordinate(shape, locator) || Shape2NearCoordinate(shape, locator));
}