Nhibernate - Инициализируют списки - Лучшая практика?

Вы пробовали Просмотр -> Данные отчета? Затем вы должны увидеть параметры в окне данных отчета. Вот так я доберусь до параметров в VS2010.

6
задан Christian Ruppert 16 June 2009 в 13:44
поделиться

2 ответа

Является ли LogMessages постоянным? Если да, то лучше никогда не раскрывать публичный сеттер. NHibernate становится странным, если вы извлекаете из базы данных, а затем заменяете этот IList новым:

var myLog = session.Get<LogRun>(1);
Assert.True(myLog.LogMessages.Count > 0);
myLog.LogMessages = new List<Log>();

Если вы заметили, NHibernate возвращает проксированный объект, и замена его на общий список приведет к тому, что он будет шатким, когда вы попытаетесь сохранить назад.

Как правило, я предпочитаю иметь частное поле, которое я инициализирую, а затем предоставляю клиенту только геттер:

public class LogRun
{
    private IList<Log> logMessages = new List<Log>();

    public virtual int Id { get; private set; } 
    public virtual DateTime StartTime { get; set; } 
    public virtual DateTime EndTime { get; set; }
    public virtual IList<Log> LogMessages { get { return logMessages; } } 
    public virtual int LogMessageCount { get { return LogMessages.Count; } }

    public void AddLogMessage(Log log)
    {
        logMessages.Add(log);
    }
}

На самом деле, я иду еще дальше, клиент получает IEnumerable <>, и я добавляю вспомогательная функция для добавления.

Моя реализация будет выглядеть как

public class LogRun
{
    private IList<Log> logMessages = new List<Log>();

    public virtual int Id { get; private set; } 
    public virtual DateTime StartTime { get; set; } 
    public virtual DateTime EndTime { get; set; }
    public virtual IEnumerable<Log> LogMessages { get { return logMessages; } } 
    public virtual int LogMessageCount { get { return LogMessages.Count(); } }

    public void AddLogMessage(Log log)
    {
        logMessages.Add(log);
    }
}
8
ответ дан 10 December 2019 в 02:52
поделиться

Я делаю то же самое, но мне также интересно, насколько велико влияние на производительность, поскольку NHibernate также будет создавать новый List <> для каждого вызова конструктора по умолчанию.

Я думаю, что мы Но повезло, и это сработает. Представьте, что NHibernate создает список LogRun с отложенной загрузкой (поэтому мы все равно помечаем все как виртуальное):

  1. NHibernate отразит LogRun и создаст производный класс
  2. NHibernate создаст прокси-список производных от LogRun class
  3. -
  4. Когда вы загружаете этот прокси-сервер, он создает экземпляры некоторых из этих производных классов, однако сначала вызывается базовый конструктор - создание нового списка <> - затем вызывается производный конструктор, создающий вместо этого proxy-list.

Фактически, мы создали список, который никогда не будем использовать.

Однако рассмотрим альтернативы:

  • Сделайте конструктор защищенным, чтобы никто не вызвал его, и создайте альтернативу. Например, статический LogRun.GetNew (); метод.
  • Разрешить общедоступный набор-доступ к IList <> и создавать его самостоятельно всякий раз, когда вы создаете новый объект.

Честно говоря, я думаю, что и то, и другое очень беспорядочно, и поскольку я (почти) уверен, что производительность накладные расходы на создание нового пустого списка при каждом вызове конструктора ограничены, это то, чего я лично придерживаюсь до сих пор .. Ну, по крайней мере, пока мой профилировщик не скажет мне иначе: P

1
ответ дан 10 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

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