在 ignite.net 中的过滤器中加入 ICacheEntryFilter

Join in ICacheEntryFilter in filters in ignite.net

我正在尝试在 Ignite.net 中实现空间查询,这是我在一个区域中查找地理点的功能

        public List<GeoPointDto> GetPointsInZone(CartesianPoint[] cartesianPoints, string zoneId)
    {
        List<GeoPointDto> reslt = new List<GeoPointDto>();

        var scanQuery = new ScanQuery<string, GeoPoint>(new SearchPointsInArea(cartesianPoints, zoneId, cache));
        IQueryCursor<ICacheEntry<string, GeoPoint>> queryCursor = cache.Query(scanQuery);

        var res = queryCursor.GetAll();
        foreach (ICacheEntry<string, GeoPoint> cacheEntry in res)
        {
            var tempPoint = new Dto.Point()
            {
                Latitude = cacheEntry.Value.Location.PointOnSurface.Y,
                Longitude = cacheEntry.Value.Location.PointOnSurface.X
            };
            reslt.Add(new GeoPointDto()
            {
                CreateDate = cacheEntry.Value.CreateDate,
                SerialNumber = "",
                Point = tempPoint
            });
        }

        return reslt;
    }

如您所见,我发送了一个带有扫描查询的过滤器来启动缓存,这是它的代码

    public class SearchPointsInArea : ICacheEntryFilter<string, GeoPoint>
{
    private ICache<string, GeoPoint> cache;
    private CartesianPoint[] BorderPoints { get; set; }
    private string ZoneId { get; set; }
    public SearchPointsInArea(CartesianPoint[] _borderPoints, string _zoneId, ICache<string, GeoPoint> _cache)
    {
        this.BorderPoints = _borderPoints;
        this.ZoneId = _zoneId;
        this.cache = _cache;
    }

    public bool Invoke(ICacheEntry<string, GeoPoint> entry)
    {
        CartesianPoint point = new CartesianPoint()
        {
            Y = entry.Value.Location.PointOnSurface.Y,
            X = entry.Value.Location.PointOnSurface.X
        };
        if (IsInPolygon(BorderPoints, point))
        {
            var queryString = "select count(p.SerialNumber) from GeoPoint as p inner join " +
                "Device as d on d.SerialNumber = p.SerialNumber inner join " +
                "Vehicle as v on v.Id = d.VehicleId " +
                "where v.ZoneId like (?) and p.SerialNumber like (?)";
            IFieldsQueryCursor query = cache.Query(new SqlFieldsQuery(queryString, ZoneId, entry.Value.SerialNumber));
            var res = query.GetAll().First();

            if (Int32.Parse(res.ToString()) > 0)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }

    }

    public bool IsInPolygon(CartesianPoint[] poly, CartesianPoint point)
    {
        var coef = poly.Skip(1).Select((p, i) =>
                                        (point.Y - poly[i].Y) * (p.X - poly[i].X)
                                      - (point.X - poly[i].X) * (p.Y - poly[i].Y))
                                .ToList();

        if (coef.Any(p => p == 0))
            return true;

        for (int i = 1; i < coef.Count(); i++)
        {
            if (coef[i] * coef[i - 1] < 0)
                return false;
        }
        return true;
    }
}

如您所见,我有 IsInPolygon 函数用于检查该区域中的点,然后还有一个 SqlFieldQuery 用于检查它们是否在该区域中(GeoPoint 对象没有 ZoneId,它们之间还有 2 个另一个对象),但是我收到这个错误

System.Runtime.Serialization.SerializationException: 'Serializing delegates is not supported on this platform.'

事实上,我需要加入我的过滤器才能实现我的目标。有什么办法吗?

您不应尝试将 ICache 传递给序列化并发送到远程。相反,你应该使用 [InstanceResource] 将远程 Ignite 实例注入你的过滤器 as shown in docs,在过滤期间请求它的缓存。