Хотел добавить мой короткий ответ в эту и без того длинную ветку. Кое-что, что не было упомянуто, является порядком приоритета операторов catch, более конкретно, вам необходимо знать область действия каждого типа исключения, которое вы пытаетесь перехватить.
Например, если вы используете исключение «catch-all» в качестве Exception , оно будет предшествовать всем остальным операторам catch, и вы, очевидно, получите ошибки компилятора, однако, если вы измените порядок в обратном порядке, вы можете связать свои выражения catch (немного анти-паттерна, я думаю), вы можете поместить тип catch-all Exception внизу, и это будет захватывать любые исключения, которые не обслуживали более высокий уровень в вашем блоке try..catch :
try
{
// do some work here
}
catch (WebException ex)
{
// catch a web excpetion
}
catch (ArgumentException ex)
{
// do some stuff
}
catch (Exception ex)
{
// you should really surface your errors but this is for example only
throw new Exception("An error occurred: " + ex.Message);
}
Я настоятельно рекомендую людям ознакомиться с этим документом MSDN:
А что насчет этого?
Где у вас есть перечисление для операции. Вместо передачи строки для словаря вы передаете тип QueryObject, который имеет тип значения и операцию для значения. Вы можете увидеть ниже.
public enum Operation
{
And,
Or
}
public class QueryObject
{
public string Value { get; set; }
public Type Type { get; set; }
public Operation Operation { get; set; }
}
public override IEnumerable<T> SelectQuery(Dictionary<string, QueryObject> dictionary)
{
string t = Convert.ToString(typeof(T).Name);
string criteria = string.Empty;
foreach (KeyValuePair<string, QueryObject> item in dictionary)
{
if (!string.IsNullOrEmpty(criteria))
{
switch (item.Value.Operation)
{
case Operation.And:
criteria += " and ";
break;
case Operation.Or:
criteria += " or ";
break;
default:
break;
}
}
if (item.Value.Type == typeof(int))
{
criteria += item.Key + " = " + item.Value + " ";
}
else
{
criteria += item.Key + " = '" + item.Value + "'";
}
}
string query = " from " + t;
if (criteria != string.Empty)
query += " where " + criteria;
return FindByHql(query);
}
Альтернативой тому, что вы делаете, является передача Expression> вместо словаря и последующий синтаксический анализ выражения Linq для того, что вы хотите. Небольшое предложение, которое я хотел бы сделать, - использовать запрос критериев вместо HQL. Конечно, синтаксический анализ выражения Linq, вероятно, намного сложнее, чем то, что у вас здесь.
Возможно, вы сможете обработать словарь и создать отличный HQL, но мне больно думать о том, чтобы сделать это таким образом. Критериальные запросы, похоже, предназначены для такого рода вещей.
Моя изначальная мысль заключалась в том, что создавать что-то подобное не слишком разумно. Вы пишете код, который генерирует HQL. Что, в свою очередь, передается в nhibernate, который генерирует SQL.
Я бы посоветовал взглянуть на запросы NHibernate критериев . Во-первых, как более простой способ динамического создания запроса NHibernate. Но также чтобы дать вам некоторое представление о том, насколько сложным может быть развертывание вашего собственного построителя динамических запросов.
Тем не менее. Если бы я делал это, я бы, вероятно, использовал NHibernate Criteria как основу для любого конструктора динамических запросов. Нет причин, по которым он не мог сгенерировать запрос, который будет использоваться другим ORM.
Более общее решение проблемы - абстрагирование вашего доступа к данным, так что если вы хотите переключить ORM, вам нужно только изменить код за вашей абстракцией.
Если вы использовали Criteria API, то уже есть функция «Запрос по примеру» (также известная как QBE), которая использует свойства сущности для генерации запросов.
Взгляните на раздел 12.6:
https://www.hibernate.org/hib_docs/nhibernate/html/querycriteria.html
Я бы предложил, возможно, создать класс со всеми необходимыми вам свойствами:
Name,
Value,
Type,
JoinType (possibly an enum with Or / And)
тогда пусть ваш метод возьмет коллекцию из них типы в отличие от словаря. Таким образом, вы можете легко проверить, нужно ли вам делать и / или, а также проверить, нужны ли вам цитаты ...