Как хранить значения базы данных в словаре в C # - PullRequest
0 голосов
/ 02 апреля 2019

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

    public static int GetCountryId(string countryName)
    {
        int countryId = 0;
        if (!string.IsNullOrEmpty(countryName))
        {
            var listOfCountries = GetCountries();
            var match = listOfCountries.FirstOrDefault(item => (item.Name).Contains(countryName));
            if (match != null)
            {
                countryId = match.Id;
            }
        }
        return countryId;
    }

    private static List<Country> GetCountries()
    {
        string query = $"SELECT Id, Name FROM Countries";
        List<Country> cases = Common.GetCollection<Country>(Properties.Settings.Default.DbConnectionString, query);
        return cases;
    }

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

Кто-нибудь знает, как я могу улучшить свой код, чтобы мне не приходилось каждый раз обращаться к БД?

Ответы [ 4 ]

0 голосов
/ 02 апреля 2019

Давайте сделаем ленивую загрузку для этого!

private Dictionary<string, Country> _countryNames = null;

public Dictionary<string, Country> CountryNames
{
    get
    {
         if(_countryNames == null)
         {
             _countryNames = new Dictionary<int, Country>();
             foreach(var country in GetCountries())
             {
                 _countryNames.Add(country.Name, country)
             }
         }
         return _countryNames;
    }
}

public static int GetCountryId(string countryName)
{
    Country result;
    CountryNames.TryGetValue(countryName, out result);
    if (result == null) return 0;
    return result.Id;
}

private static IEnumerable<Country> GetCountries()
{
    string query = "SELECT Id, Name FROM Countries";
    return Common.GetCollection<Country>(Properties.Settings.Default.DbConnectionString, query);
}

Но обычно даже лучше позволить базе данных делать свое дело: запускать запрос там, где необходимо, где вы передаете строку фильтра в базу данных,К сожалению, Common.GetCollection<T>() скрывает эту способность от нас.Переменная query должна выглядеть примерно так:

string query = "SELECT Id, Name FROM Countries WHERE Name = @CountryName";

, но из поставленного здесь вопроса не ясно, как задать значение параметра @CountryName. НЕ нужно всего лишь использовать подстановку строк или интерполяцию, чтобы включить значение непосредственно в строку запроса.Это было бы очень плохо ;он создает серьезную форму безопасности, выпущенную под названием SQL-инъекция.

0 голосов
/ 02 апреля 2019

Измените ваш метод так:

private static List<Country> countries;

private static List<Country> GetCountries()
{
    if (countries == null || countries.Count == 0)
    {
        string query = $"SELECT Id, Name FROM Countries";
        countries = Common.GetCollection<Country>(Properties.Settings.Default.DbConnectionString, query);
    }

    return countries;
}
0 голосов
/ 02 апреля 2019

Как насчет создания статического конструктора для заполнения словаря идентификаторов стран при первом запуске вашей программы, чтобы вам приходилось запрашивать базу данных только один раз. Тогда вызовы GetCountryId могут просто использовать этот словарь?

private static Dictionary<string, int> CountryIds;

public static NameOfYourClass(){
    CountryIds = new Dictionary<string, int>();
    string query = $"SELECT Id, Name FROM Countries";
    List<Country> cases = Common.GetCollection<Country>(Properties.Settings.Default.DbConnectionString, query);
    foreach (country Country in cases)
    {
        CountryIDs.Add(Country.Name, Country.Id);
    }        
}

public static int GetCountryId(string countryName)
{
    if(!CountryIds.Contains(countryName) return 0;
    return CountryIds[countryName];
}
0 голосов
/ 02 апреля 2019

У вас может быть публичный словарь, подобный этому:

public static Dictionary<int, string> countries = new Dictionary<int, string>();

Метод заполняет словарь, если он не был заполнен ранее;

private static void GetCountries()
    {
        if(countries.Count == 0)
        {
              string query = $"SELECT Id, Name FROM Countries";
              countries = Common.GetCollection<Country>(Properties.Settings.Default.DbConnectionString, query)
              .ToDictionary(x => x.Id, x=> x.Name);
        }
    }


public static int GetCountryId(string countryName)
{
    return countries.Contains(countryName) CountryIds[countryName] : 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...