Generics и доступ к базе данных
-
06-07-2019 - |
Вопрос
У меня есть следующий метод, который я могу передать лямбда-выражением для фильтрации моих результатов, а затем метод обратного вызова, который будет работать со списком результатов. Это только одна конкретная таблица в моей системе, я буду использовать эту конструкцию снова и снова. Как я могу создать универсальный метод, скажем, DBget, который принимает в качестве параметра таблицу (сущность службы данных ADO.NET, если честно) и передать фильтр (лямбда-эксперимент)?
public void getServiceDevelopmentPlan(Expression<Func<tblServiceDevelopmentPlan, bool>> filter, Action<List<tblServiceDevelopmentPlan>> callback)
{
var query = from employerSector in sdContext.tblServiceDevelopmentPlan.Where(filter)
select employerSector;
var DSQuery = (DataServiceQuery<tblServiceDevelopmentPlan>)query;
DSQuery.BeginExecute(result =>
{
callback(DSQuery.EndExecute(result).ToList<tblServiceDevelopmentPlan>());
}, null);
}
Мой первый пример:
public delegate Action<List<Table>> DBAccess<Table>(Expression<Func<Table, bool>> filter);
Решение
Если вы используете Linq для Ado.NET Dataservices или WCF Dataservices, ваша модель создаст много типизированных. Вообще, хотя вы будете выбирать и фильтровать. Вам нужно следующее, тогда все ваши методы просто конфетка поверх этого:
Тип запроса 1 - один фильтр, возвращает список:
public void makeQuery<T>(string entity, Expression<Func<T, bool>> filter, Action<List<T>> callback)
{
IQueryable<T> query = plussContext.CreateQuery<T>(entity).Where(filter);
var DSQuery = (DataServiceQuery<T>)query;
DSQuery.BeginExecute(result =>
{
callback(DSQuery.EndExecute(result).ToList<T>());
}, null);
}
Тип запроса 2 - один фильтр, возвращает одну сущность:
public void makeQuery (строковая сущность, выражение > фильтр, обратный вызов действия) {Р>
IQueryable<T> query = plussContext.CreateQuery<T>(entity).Where(filter);
var DSQuery = (DataServiceQuery<T>)query;
DSQuery.BeginExecute(result =>
{
callback(DSQuery.EndExecute(result).First<T>());
}, null);
}
Вам нужно перегрузить их и заменить фильтр на простой массив фильтров
Expression<Func<T, bool>>[] filter
И повторите для одиночного и списка возвратов.
Объедините это в одноэлементный файл, если вам нужен один текстовый текстовый код, или следите за массивом контекстов в какой-то гибридной фабрике / одноместном коде, и вас нет. Позвольте конструктору взять контекст или, если он не указан, используйте его, и вас нет.
Затем я использую это в большой строке, но все в одном месте:
GenericQuery.Instance.Create().makeQuery<tblAgencyBranches>("tblAgencyBranches", f => f.tblAgencies.agencyID == _agency.agencyID, res => { AgenciesBranch.ItemsSource = res; });
Это может показаться сложным, но оно скрывает много асинхронного волшебства, и в некоторых случаях его можно вызывать прямо из обработчиков кнопок. Не столько трехуровневая система, сколько экономия времени.