Использование динамического LINQ (или Generics) для запроса / фильтрации таблиц Azure

Итак, вот моя дилемма. Я пытаюсь использовать Dynamic LINQ для анализа фильтра поиска для получения набора записей из таблицы Azure. В настоящее время я могу получить все записи с помощью объекта GenericEntity, определенного ниже:

public class GenericEntity
{
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }

    Dictionary<string, object> properties = new Dictionary<string, object>();
    /* "Property" property and indexer property omitted here */
}

Я могу полностью заполнить его, используя событие ReadingEntity объекта TableServiceContext (называемого OnReadingGenericEvent). Следующий код - это то, что фактически извлекает все записи и , надеюсь, фильтр (как только он заработает).

public IEnumerable<T> GetTableRecords(string tableName, int numRecords, string filter)
{
    ServiceContext.IgnoreMissingProperties = true;

    ServiceContext.ReadingEntity -= LogType.GenericEntity.OnReadingGenericEntity;
    ServiceContext.ReadingEntity += LogType.GenericEntity.OnReadingGenericEntity;

    var result = ServiceContext.CreateQuery<GenericEntity>(tableName).Select(c => c);
    if (!string.IsNullOrEmpty(filter))
    {
        result = result.Where(filter);
    }
    var query = result.Take(numRecords).AsTableServiceQuery<GenericEntity>();
    IEnumerable<GenericEntity> res = query.Execute().ToList();

    return res;
}

У меня есть производные типы TableServiceEntity для всех таблиц, которые я определил, поэтому я могу получить все свойства / типы с использованием Reflection. Проблема с использованием класса GenericEntity в динамическом запросе LINQ для фильтрации заключается в том, что объект GenericEntity НЕ имеет каких-либо свойств, которые я пытаюсь фильтровать, поскольку они на самом деле просто словарные записи (ошибки динамического запроса отсутствуют). Я могу разобрать фильтр для всех имен свойств этого конкретного типа и обернуть

"Property[" + propName + "]" 

каждое свойство (найденное с помощью функции распознавания типов и отражения). Однако это кажется немного ... излишним. Я пытаюсь найти более элегантное решение, но поскольку мне действительно нужно указать тип в ServiceContext.CreateQuery <>, это несколько затрудняет.

Итак, я предполагаю, что мой главный вопрос таков: Как я могу использовать динамические классы или универсальные типы с этой конструкцией, чтобы иметь возможность использовать динамические запросы для фильтрации? Таким образом, я могу просто взять фильтр из текстового поля (например, «item_ID> 1023000») и просто динамически сгенерировать типы TableServiceEntity.

Я могу использовать другие способы решения этой проблемы, но с тех пор, как начал используя Dynamic LINQ, можно также попробовать и динамические классы.

Edit: Итак, у меня есть динамический класс, генерируемый первоначальным выбором с использованием некоторого отражения, но я сталкиваюсь с препятствием при сопоставлении типов GenericEntity.Properties в различные связанные классы записей таблицы (производные классы TableServiceEntity) и их типы свойств. Основная проблема по-прежнему заключается в том, что я должен изначально использовать определенный тип данных даже для создания запроса, поэтому я m с использованием типа GenericEntity, который содержит только пары KV. Это в конечном итоге мешает мне фильтровать, так как я не могу выполнять операторы сравнения (>, <, = и т. Д.) С типами объектов.

Вот код, который у меня теперь есть для отображения в динамический класс:

var properties = newType./* omitted */.GetProperties(
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.Public);

string newSelect = "new(" + properties.Aggregate("", (seed, reflected) => seed += string.Format(", Properties[\"{0}\"] as {0}", reflected.Name)).Substring(2) + ")";
var result = ServiceContext.CreateQuery<GenericEntity>(tableName).Select(newSelect);

Может быть, мне просто изменить метод properties.Aggregate, добавив к разделу «Свойства [...]» префикс отраженного.PropertyType? Таким образом, новая строка выбора будет выглядеть так:

string newSelect = "new(" + properties.Aggregate("", (seed, reflected) => seed += string.Format(", ({1})Properties[\"{0}\"] as {0}", reflected.Name, reflected.PropertyType)).Substring(2) + ")";

Edit 2: Итак, теперь я наткнулся на препятствие. Я могу сгенерировать анонимные типы для всех таблиц, чтобы получить все нужные мне значения, но LINQ не справляется с моими действиями, независимо от того, что я делаю для фильтра. Я указал причину выше (нет операторов сравнения для объектов), но проблема я Сейчас мы пытаемся указать параметр типа для метода расширения Dynamic LINQ, чтобы он принял схему нового типа объекта. И тут не особо везет ... Буду держать вас в курсе.

1
задан SPFiredrake 17 September 2010 в 22:01
поделиться