Исключите Вас станд.:: bitset? Наборы флагов - то, для чего это. Сделайте
typedef std::bitset<4> RecordType;
затем
static const RecordType xNew(1);
static const RecordType xDeleted(2);
static const RecordType xModified(4);
static const RecordType xExisting(8);
, поскольку существует набор перегрузок оператора для bitset, можно теперь сделать
RecordType rt = whatever; // unsigned long or RecordType expression
rt |= xNew; // set
rt &= ~xDeleted; // clear
if ((rt & xModified) != 0) ... // test
Или что-то очень похожее на это - я ценил бы любые исправления, так как я не протестировал это. Можно также обратиться к битам индексом, но обычно лучше определить только один набор констант, и константы RecordType, вероятно, более полезны.
Принятие Вы исключили bitset, я голосую за перечисление .
я не покупаю тот кастинг перечислений, серьезный недостаток - хорошо, таким образом, это является немного шумным, и присвоение значения из диапазона к перечислению является неопределенным поведением, таким образом, теоретически возможно выстрелить себе в ногу на некоторых необычных реализациях C++. Но если Вы только делаете это, когда необходимый (который является при движении от интервала до перечисления iirc), это - совершенно нормальный код, который люди видели прежде.
я сомнителен о любой стоимости пространства перечисления, также. переменные uint8 и параметры, вероятно, не будут использовать никого меньше стека, чем ints, поэтому только устройство хранения данных в вопросах классов. Существуют некоторые случаи, где упаковка нескольких байтов в структуре победит (в этом случае, можно бросить перечисления в и из uint8 устройства хранения данных), но обычно дополнение уничтожит преимущество во всяком случае.
, Таким образом, перечисление не имеет никаких недостатков по сравнению с другими, и поскольку преимущество дает Вам немного безопасности типов (Вы не можете присвоить некоторое случайное целочисленное значение, явно не бросая), и очевидные способы обращения ко всему.
Для предпочтения я также поместил "= 2" в перечислении, между прочим. Это не необходимо, но "принцип наименьшего количества удивления" предлагает, чтобы все 4 определения выглядели одинаково.
Вы можете прикрепить IInterceptor
к своему NH ISession
, а затем использовать метод OnPrepareStatement ()
для перехвата (даже изменить ) SQL.
Вы можете использовать конфигурацию Log4Net для захвата используемого SQL. Для начала вам нужно создать собственный аппендер, например:
using System;
using System.Collections.Generic;
using log4net.Appender;
using log4net.Core;
public class NHibernateQueryAppender : AppenderSkeleton
{
private static List<string> s_queries = new List<string>();
private static int s_queryCount = 0;
public static IList<string> CurrentQueries
{
get { return s_queries.AsReadOnly(); }
}
public static int CurrentQueryCount
{
get { return s_queryCount; }
}
public static void Reset()
{
s_queryCount = 0;
s_queries.Clear();
}
protected override void Append(LoggingEvent loggingEvent)
{
s_queries.Add(loggingEvent.RenderedMessage);
s_queryCount++;
}
}
Затем сконфигурируйте log4net так:
<log4net>
<...other config...>
<appender name="nhquerycheck" type="NHibernateExecutor.Loggers.NHibernateQueryAppender, NHibernateExecutor" />
<logger name="NHibernate.SQL">
<level value="DEBUG"/>
<appender-ref ref="nhquerycheck" />
</logger>
</log4net>
Вышеупомянутый класс может быть запрошен во время выполнения, например, для отображения вывода sql на экран
Редактировать: по какой-то причине сообщение вышло некорректно, поэтому нашел пример в сети http://nhforge.org/blogs/nhibernate/archive/2008/09/06/how-to-configure-log4net-for-use-with-nhibernate.aspx
Лично я использую для этого инструмент «NHibernate Profiler». Это стоит своих денег, поскольку он также хорошо анализирует использование вами NHibernate и выявляет потенциальные проблемы.