Мой опыт работы с NHibernate заключается в том, что, несмотря на то, что он обладает множеством функций и очень высокой производительностью, вам, в конечном счете, нужно стать экспертом NHibernate, чтобы исправить непредвиденное поведение. Прочитав ответы про-NHibernate и увидев
Хм, возможно, он использует долго работает
Сессии (сессия на бизнес
Модель транзакции), и в таком
подход, используя идентичность
обескуражен, так как это ломает ваши
единичная работа (необходимо промыть напрямую
после вставки новой сущности).
Решение может быть, чтобы бросить
идентичность и использовать идентификатор HiLo
генератор.
иллюстрирует именно то, что я имею в виду.
Что я сделал, так это создал базовый класс, смоделированный несколько по шаблону ActiveRecord, от которого я наследую, и помечаю унаследованный класс с атрибутами, которые прикрепляют его к хранимой процедуре, каждый для выбора, вставки, обновления и удаления. Базовый класс использует Reflection для чтения атрибутов и назначения значений свойств класса параметрам SP, а в случае Select () присваивает значения столбца результирующего SQLDataReader свойствам списка обобщенных элементов.
Вот как выглядит DataObjectBase:
interface IDataObjectBase<T>
{
void Delete();
void Insert();
System.Collections.Generic.List<T> Select();
void Update();
}
Это пример класса данных, производных от него:
[StoredProcedure("usp_refund_CustRefundDetailInsert", OperationType.Insert)]
[StoredProcedure("usp_refund_CustRefundDetailSelect", OperationType.Select)]
[StoredProcedure("usp_refund_CustRefundDetailUpdate", OperationType.Update)]
public class RefundDetail : DataObjectBase<RefundDetail>
{
[StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
[StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Output)]
[StoredProcedureParameter(null, OperationType.Select, ParameterDirection.Input)]
[ResultColumn(null)]
public int? RefundDetailId
{ get; set; }
[StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
[StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
[StoredProcedureParameter(null, OperationType.Select, ParameterDirection.Input)]
[ResultColumn(null)]
public int? RefundId
{ get; set; }
[StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
[StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
[ResultColumn(null)]
public int RefundTypeId
{ get; set; }
[StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
[StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
[ResultColumn(null)]
public decimal? RefundAmount
{ get; set; }
[StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
[StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
[ResultColumn(null)]
public string ARTranId
{ get; set; }
}
Я знаю, что, похоже, я заново изобретаю колесо, но все библиотеки, которые я обнаружил, либо слишком сильно зависели от других библиотек (например, ActiveRecord + NHibernate, что было довольно близко), либо были слишком сложны в использовании и администрировать.
Библиотека, которую я сделал, очень легкая (возможно, пара сотен строк C #) и не делает ничего, кроме как присваивает значения параметрам и выполняет SP. Он также очень хорошо подходит для генерации кода, поэтому в конечном итоге я не буду писать код доступа к данным. Мне также нравится, что он использует экземпляр класса вместо статического класса, так что я могу передавать данные в запросы без некоторого неудобного сбора критериев или HQL. Select () означает «стань больше как я».