Как избежать проверки на нулевую частную собственность при ленивой загрузке? - PullRequest
1 голос
/ 23 марта 2012

У меня есть класс с примерно 20 полями, которые загружаются из базы данных SQL при загрузке. В настоящее время я вызываю метод загрузки данных сразу после конструктора, который вызывает процедуру SQL и заполняет все необходимые поля. Иногда я не могу получить доступ к этим 20 полям вообще, я добавляю дополнительную стоимость вызова SQL, хотя это не было необходимо. Поэтому я изменил все свойства, чтобы иметь связанное частное свойство, и когда программа вызывает открытое свойство, сначала я проверяю частное свойство, и если оно пустое, это означает, что нам нужно загрузить данные из sql, поэтому я вызываю метод load. Это прекрасно работает, но когда я вижу код, повторяется шаблон проверки на ноль и загрузки SQL-запроса. Есть ли лучший способ сделать это?

private string _name;
public string Name 
{
   get {
      if (_name == null)
         LoadData(); //this popultes not just but all the properties
      return _name;
   }
}

Ответы [ 6 ]

5 голосов
/ 25 марта 2012

Кстати, C # теперь имеет стандартную реализацию отложенных загрузчиков. Почему бы не использовать его вместо предоставления флагов isSomethingLoaded? :)

public class Bar
{
    private Lazy<string> _name = new Lazy<string>(() => LoadString());

    public string Name
    {
        get { return _name.Value; }
    }
}

В случае нестатического метода LoadString, lazy-loader должен быть инициализирован в конструкторе;

4 голосов
/ 23 марта 2012

Нет, это правильно. Вот статья в Википедии . Затраты на проверку нуля будут очень минимальными по сравнению с ненужными вызовами базы данных. Теперь, если пользователи программы действительно используют значения в 99% случаев, я бы сказал, что этот шаблон не нужен.

Только одно предупреждение: если какое-либо из ваших значений может быть нулевым, вы будете выполнять ненужные вызовы базы данных. Возможно, было бы лучше сделать что-то подобное (что будет еще более быстрой проверкой, поскольку это всего лишь небольшая проверка):

//Constructor default to not loaded
bool isLoaded = false;

private string _name;
public string Name 
{
   get {
      if (!isLoaded)
         LoadData(); //this popultes not just but all the properties
      return _name;
   }
}   

private LoadData()
{
    //Load Data
    isLoaded = true;
}
0 голосов
/ 23 марта 2012

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

public class Singleton123
{
    private static readonly string _property1 = ClassLoadData.LoadData();

    public static string MyProperty1
    {
        get
        {
            return _property1;
        }
    }

}

public class ClassLoadData
{
    public static string LoadData()
    {
        // any logic to load data
        return "test";
    }
}

Позвоните собственности, как показано ниже

Singleton123 obj = new Singleton123();
        string stra = Singleton123.MyProperty1;
        string strb = Singleton123.MyProperty1;

это свойство будет загружено только один раз.

0 голосов
/ 23 марта 2012

Я думаю, вы должны рассмотреть структуру вашего приложения.Зачем вам даже создавать экземпляр класса, если вы не собираетесь использовать свойства?Я считаю, что на самом деле вам удобнее вызывать SQL после кода конструктора, но создавать объекты вашего класса только в том случае, если вы собираетесь его использовать.Другое более гибкое решение - сделать LoadData общедоступной и при необходимости вызывать ее из экземпляра объекта.

0 голосов
/ 23 марта 2012

Одна вещь, которую вы можете сделать, это извлечь, если в отдельный метод, чтобы каждое свойство содержало только один дополнительный вызов:

void EnsureData()
{
      if (!dataLoaded) 
         LoadData(); //this populates all the properties 
}

public string Name {
   get { 
      EnsureData();
      return _name; 
   } 
}
0 голосов
/ 23 марта 2012

Ну, вы могли бы изменить его на:

if (!initialized)
    LoadData();

И в вашем наборе LoadData инициализировано как true, но это действительно не меняет его семантику.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...