Я могу передать в T.Property? Кроме того, идеи для улучшения этого метода?

Хотел добавить мой короткий ответ в эту и без того длинную ветку. Кое-что, что не было упомянуто, является порядком приоритета операторов 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:

Иерархия исключений

5
задан George Stocker 18 June 2009 в 15:44
поделиться

5 ответов

А что насчет этого?

Где у вас есть перечисление для операции. Вместо передачи строки для словаря вы передаете тип 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);
}
3
ответ дан 14 December 2019 в 19:23
поделиться

Альтернативой тому, что вы делаете, является передача Expression> вместо словаря и последующий синтаксический анализ выражения Linq для того, что вы хотите. Небольшое предложение, которое я хотел бы сделать, - использовать запрос критериев вместо HQL. Конечно, синтаксический анализ выражения Linq, вероятно, намного сложнее, чем то, что у вас здесь.

Возможно, вы сможете обработать словарь и создать отличный HQL, но мне больно думать о том, чтобы сделать это таким образом. Критериальные запросы, похоже, предназначены для такого рода вещей.

0
ответ дан 14 December 2019 в 19:23
поделиться

Моя изначальная мысль заключалась в том, что создавать что-то подобное не слишком разумно. Вы пишете код, который генерирует HQL. Что, в свою очередь, передается в nhibernate, который генерирует SQL.

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

Тем не менее. Если бы я делал это, я бы, вероятно, использовал NHibernate Criteria как основу для любого конструктора динамических запросов. Нет причин, по которым он не мог сгенерировать запрос, который будет использоваться другим ORM.

Более общее решение проблемы - абстрагирование вашего доступа к данным, так что если вы хотите переключить ORM, вам нужно только изменить код за вашей абстракцией.

1
ответ дан 14 December 2019 в 19:23
поделиться

Если вы использовали Criteria API, то уже есть функция «Запрос по примеру» (также известная как QBE), которая использует свойства сущности для генерации запросов.

Взгляните на раздел 12.6:

https://www.hibernate.org/hib_docs/nhibernate/html/querycriteria.html

0
ответ дан 14 December 2019 в 19:23
поделиться

Я бы предложил, возможно, создать класс со всеми необходимыми вам свойствами:

Name,
Value,
Type,
JoinType (possibly an enum with Or / And)

тогда пусть ваш метод возьмет коллекцию из них типы в отличие от словаря. Таким образом, вы можете легко проверить, нужно ли вам делать и / или, а также проверить, нужны ли вам цитаты ...

1
ответ дан 14 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: