Для более детального понимания перехода с SQLWhereLanguageDef на FunctionBuilder в данной статье приведены основные примеры рефактора, который был осуществлён на нескольких прикладных проектах.
funcSQL
Особые изменения отсутствуют.
Функция ограничения с использованием langdef
Function lf = LangDef.GetFunction(LangDef.funcSQL, "sql");
Функция ограничения с использованием FunctionBuilder
Function lf = FunctionBuilder.BuildSQL("sql");
funcNOT
Особые изменения отсутствуют.
Функция ограничения с использованием langdef
Function FuncTrue = LangDef.GetFunction(LangDef.funcEQ, 1, 1);
Function lf = LangDef.GetFunction(LangDef.funcNOT, FuncTrue);
Функция ограничения с использованием FunctionBuilder
Function FuncTrue = FunctionBuilder.BuildTrue();
Function lf = FunctionBuilder.BuildNot(FuncTrue);
funcEQ
Ограничение по первичным ключам сопровождается обращением к свойству __PrimaryKey
, что не уменьшает сложность и читаемость кода.
Функция ограничения с использованием langdef
VariableDef PrimaryKeyVarDef = new VariableDef(LangDef.GuidType, SQLWhereLanguageDef.StormMainObjectKey);
Function lf = LangDef.GetFunction(
LangDef.funcEQ,
PrimaryKeyVarDef,
TestDataObject1.__PrimaryKey);
Функция ограничения с использованием FunctionBuilder
Function lf = FunctionBuilder.BuildEquals(TestDataObject1);
funcIN - собственный первичный ключ
Главным неудобством funcIN
является необходимость передавать вторым аргументом нетипизированный массив, первым элементом которого должен быть путь свойства. В FunctionBuilder
данный недостаток довольно изящно преодолён - для построения функции ограничения по первичным ключам не обязательно указывать SQLWhereLanguageDef.StormMainObjectKey
, т.е. не обязательно указывать путь свойства (в данном случае).
Функция ограничения с использованием langdef
var clientKeys = new List<object> { new VariableDef(langdef.GuidType, SQLWhereLanguageDef.StormMainObjectKey) };
clientKeys.AddRange(ordKeys);
Function lf = langdef.GetFunction(langdef.funcIN, clientKeys.ToArray());
Функция ограничения с использованием FunctionBuilder
Function lf = FunctionBuilder.BuildIn(ordKeys);
funcIN - поле класса
Для ограничения объектов по массиву перечислений не обязательно использовать EnumCaption.GetCaptionFor
.
Функция ограничения с использованием langdef
Function lf = langdef.GetFunction(langdef.funcIN, new VariableDef(langdef.StringType, "СпособВвода"),
EnumCaption.GetCaptionFor(СпВвода),
EnumCaption.GetCaptionFor(tСпособВвода.ИмпортАСПенсия));
Функция ограничения с использованием FunctionBuilder
Function lf = FunctionBuilder.BuildIn<Происхождение>(x => x.СпособВвода, СпВвода, tСпособВвода.ИмпортАСПенсия);
funcExists
Синтаксис довольно сильно упрощен, метод-обертка BuildExists
имеет два перегрузки:
- Function BuildExists(DetailVariableDef dvd, Function function = null)
- Function BuildExists(string connectMasterPorp, View view, Function function = null)
Основным отличием является необязательность передачи функции, по которой будет осуществлена выборка.
Функция ограничения с использованием langdef
Function FuncTrue = LangDef.GetFunction(LangDef.funcEQ, 1, 1);
string ConnectMasterProp = Information.ExtractPropertyName<TestDataObjectDetail>(x => x.TestDataObject);
DetailVariableDef DetVarDef = FunctionHelper.GetDetailVarDef(TestDataObjectDetail.Views.D, ConnectMasterProp);
Function lf = LangDef.GetFunction(LangDef.funcExist, DetVarDef, FuncTrue);
Функция ограничения с использованием FunctionBuilder
Перегрузка 1:
string ConnectMasterProp = Information.ExtractPropertyName<TestDataObjectDetail>(x => x.TestDataObject);
DetailVariableDef DetVarDef = FunctionHelper.GetDetailVarDef(TestDataObjectDetail.Views.D, ConnectMasterProp);
Function lf = FunctionBuilder.BuildExists(DetVarDef);
Перегрузка 2:
string ConnectMasterProp = Information.ExtractPropertyName<TestDataObjectDetail>(x => x.TestDataObject);
Function lf = FunctionBuilder.BuildExists(ConnectMasterProp, TestDataObjectDetail.Views.D, DetVarDef);
Отсутствующий функционал
Более внимательный читатель может заменить, что в FunctionBuilder
отсутствуют такие функции как DatePart
, YearPart
, Count
, SUM
, MAX
и др. Данные функции не были “обернуты” умышлено, т.к. FunctionBuilder
ориентирован на построение логических функций, каждая из которых в результате возвращает булево значение. Однако, многие методы FunctionBuilder
имеют перегрузки, позволяющее передавать Function
в качестве аргументов.
Итого
Переход от LangDef.GetFunction
к FunctionBuilder
несет в себе не только количественные изменения в виде уменьшения длины кода, но и качественные:
- значительное повышение читаемости кода как для простых функций, так и для громоздких и многоэтажных
- сведение к минимуму ошибок при указании путей свойств за счет применения лямбд
- упрощение работы с первичными ключами за счет использования
PKHelper