Создание динамических запросов с инфраструктурой сущностей
Я хотел бы знать, что является лучшим способом создания динамических запросов с каркасом сущностей и linq.
Я хочу создать службу с множеством параметров для сортировки и фильтрации (более 50). Я получаю объект от gui, где они будут заполнены... и запрос будет выполнен из одного метода службы.
Я огляделся и увидел, что могу динамически создать строку, которая может быть выполнена в конце моего метода. Мне это не очень нравится. Есть лучший способ сделать это? Предпочтительно тип safe с проверкой компиляции?
Ответы
Ответ 1
Шаг за шагом можно создать IQueryable<T>
. Предполагая, что у вас есть класс FilterDefinition
, который описывает, как пользователь хочет фильтровать...
public class FilterDefinition
{
public bool FilterByName { get; set; }
public string NameFrom { get; set; }
public string NameTo { get; set; }
public bool FilterByQuantity { get; set; }
public double QuantityFrom { get; set; }
public double QuantityTo { get; set; }
}
... тогда вы можете построить такой запрос:
public IQueryable<SomeEntity> GetQuery(FilterDefinition filter)
{
IQueryable<SomeEntity> query = context.Set<SomeEntity>();
// assuming that you return all records when nothing is specified in the filter
if (filter.FilterByName)
query = query.Where(t =>
t.Name >= filter.NameFrom && t.Name <= filter.NameTo);
if (filter.FilterByQuantity)
query = query.Where(t =>
t.Quantity >= filter.QuantityFrom && t.Quantity <= filter.QuantityTo);
return query;
}
Ответ 2
Единственным другим способом, который я знаю, было бы создание IQueryable на основе ваших фильтров.
public List<Contact> Get(FilterValues filter)
{
using (var context = new AdventureWorksEntities())
{
IQueryable<Contact> query = context.Contacts.Where(c => c.ModifiedDate > DateTime.Now);
if (!string.IsNullOrEmpty(filter.FirstName))
{
query = query.Where(c => c.FirstName == filter.FirstName);
}
if (!string.IsNullOrEmpty(filter.LastName))
{
query = query.Where(c => c.LastName == filter.LastName);
}
return query.ToList();
}
}
Ответ 3
Я создал общий репозиторий, который должен вам помочь. Он поддерживает единый API для запроса и сортировки как по известным, так и по динамическим полям:
//Filter on known fields
var keyboard = Query<Product>.Create(p=>p.Category=="Keyboard");
var keyboards = repository.Get(keyboard);
//Or filter on dynamic fields
var filter = Query<Product>.Create("Category", OperationType.EqualTo, "Keyboard")
var filteredKeyboards = repository.Get(filter);
//You can also combine two queries togather
var filterdKeyboards2 = repository.Get(keyboard.And(filter))
//Filter it on known fields
var orderedKeyboard = keyboard.OrderBy(o=>o.Asc(p=>p.Name));
var orderedKeyboards = repository.Get(orderedKeyboard);
//Or filter it on dynamic fields
var userOrdering = keyboard.OrderBy(o=>o.Asc("Name"));
var orderedKeyboards2 = repository.Get(userOrdering);
Я не знаю об объекте поиска /DTO, который вы получаете, но вы можете легко создать общий объект поиска /DTO и можете сопоставить его с объектом Query в нескольких строках кода. Я использовал его в прошлом вокруг службы WCF, и он работал очень хорошо для меня.
Ответ 4
Вы можете изучить создание службы с использованием служб данных WCF и динамическое создание URI для запроса модели вашего объекта.