Построение предложения where для Entity Framework - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть следующий запрос

var query = from demand in _context.demand as IQueryable<DemandEntity>
            join consumable in _context.demand_consumable on demand.id equals consumable.demand_id
            join ad in _context.address on demand.address_id equals ad.id into tmp
            from ad in tmp.DefaultIfEmpty()
            where category == consumable.category
            select new { demand, consumable, ad};

, который выберет все требования, которые имеют расходные материалы в данной категории (которые работают).

Так как они могут быть расположены где угодно, я хочу выбрать только те, которые имеют местоположение, которое близко к данной центральной точке.

Из этой центральной точки и данного радиуса я вычисляю различные условия:

if ((boundingBox.Type & BoundingBoxType.WrappsNorthPole) != 0)
{
    var south = Convert.ToDecimal(Math.Min(
        boundingBox.NorthEastCorner.Latitude,
        boundingBox.SouthEastCorner.Latitude
    ));

    query = query.Where(a => south <= a.ad.latitude);
}
else if ((boundingBox.Type & BoundingBoxType.WrappsSouthPole) != 0)
{
    var north = Convert.ToDecimal(Math.Min(
        boundingBox.NorthEastCorner.Latitude,
        boundingBox.SouthEastCorner.Latitude
    ));

    query = query.Where(a => a.ad.latitude <= north);
}
else // wraps around the horizontal
{
    var west = Convert.ToDecimal(Math.Min(
                boundingBox.SouthWestCorner.Longitude,
                boundingBox.NorthWestCorner.Longitude));

    var east = Convert.ToDecimal(Math.Max(
        boundingBox.NorthEastCorner.Longitude,
        boundingBox.SouthEastCorner.Longitude));

    var south
        = Convert.ToDecimal(boundingBox.SouthWestCorner.Latitude);
    var north
        = Convert.ToDecimal(boundingBox.NorthWestCorner.Latitude);

    query = query
        .Where(a => south <= a.ad.latitude)
        .Where(a => a.ad.latitude <= north);

    if (boundingBox.Type == BoundingBoxType.Normal)
    {
        query = query
            .Where(a => west <= a.ad.longitude)
            .Where(a => a.ad.longitude <= east);
    }
    else
    {
        query = query
            .Where(a =>
                west <= a.ad.longitude
                || a.ad.longitude <= east
            );
    }
}

Так как мне нужны эти логи c для нескольких запросов я хотел преобразовать его в метод, подобный

public IQueryable<T> AddToQuery<T>(IQueryable<T> query)

, который находится в моем классе BoundingBox. Проблема в том, что T должен быть анонимным типом, который создается запросом, но, поскольку он анонимный, мой новый метод не может знать о поле.

Я пробовал подписи типа

public IQueryable<T> AddToQuery<T>(IQueryable<T> query, Func<T, Address> selector)

Но для этого Entity Framework жалуется на невозможность создания команды SQL.

Как я могу создать такие условия отдельно от метода, в котором создается запрос?

Я также пытался создать ValueTuple вместо анонимного типа, но безрезультатно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...