2016-10-03 5 views
0

У меня есть приложение-служба Windows, с которым я хочу управлять настройкой для сайта asp.net. По мере увеличения моего приложения мой список настроек в файле app.config также вырос. Итак, я решил переместить эти настройки в таблицу в своем SQLDB, чтобы иметь возможность отслеживать их и давать мне способ изменить настройки с сайта администратора. У меня возникла проблема, когда я пытаюсь сохранить тип значения параметра в таблице, а затем использовать его, чтобы изменить значение свойства на сохраненный тип. Например, у меня довольно много определённых TimeSpan. В таблице SQL данные будут выглядеть следующим образом.Перемещение параметров app.config в db и использование типа значения для динамического задания возвращаемого типа данных

guid settingName  settingValue settingType 
936767f5-63b5-4844-9991-29f6f92c53f2 SMTimeStart 12:00:00 TimeSpan 

Я пытаюсь использовать следующий код, чтобы вытащить настройки и вернуть их в правильном типе.

public class SettingDataValue 
    { 
     public Guid guid { get; set; } 
     public string SettingName { get; set; } 
     public string SettingValue { get; set; } 
     public string SettingType { get; set; } 


    } 
    public static dynamic getSettingFromDB(string name) 
    { 
     SettingDataValue s = new SettingDataValue(); 
     using (IDbConnection _db = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString), commandTimeout = null) 
     { 
      s = _db.Query<SettingDataValue>("Select Guid, SettingName, SettingValue ,SettingType from SiteSettings where settingName = '" + name + "'").SingleOrDefault(); 
     } 
     PropertyInfo propertyInfo = s.GetType().GetProperty(s.SettingType); 
     propertyInfo.SetValue(s, Convert.ChangeType(s.SettingValue, propertyInfo.PropertyType), null); 

     return s.SettingValue; 
    } 

Однако, когда я запускаю это я получаю пустую ссылку исключение на

propertyInfo.SetValue(s, Convert.ChangeType(s.SettingValue, propertyInfo.PropertyType), null); 

Я знаю, что запрос работает, когда я проверить его и посмотреть его с SQL Profiler. Любые мысли или предложения?

ответ

1

Так что пара вещей у меня была не так. Как сказал Дэвид, мне не нужно было использовать отражение, чтобы получить тип. Вместо этого мне нужно было использовать метод Type.GetType для синтаксического анализа текста. Кроме того, второе дело, что типы данных должны быть пространством имен, записанным с ними.

Вот обновленный код, который сейчас работает.

public class SettingDataValue 
    { 
     public Guid guid { get; set; } 
     public string SettingName { get; set; } 
     public string SettingValue { get; set; } 
     public string SettingType { get; set; } 

    } 
    public static dynamic getSettingFromDB(string name) 
    { 

     SettingDataValue s = new SettingDataValue(); 
     using (IDbConnection _db = new SqlConnection(ConfigurationManager.ConnectionStrings["NetworkCafeConnectionString"].ConnectionString)) 
     { 
      s = _db.Query<SettingDataValue>("Select guid, SettingName, SettingValue ,SettingType from SiteSettings where SettingName = '" + name + "'").FirstOrDefault(); 
     } 
     Type type = Type.GetType(s.SettingType); 
     var converter = TypeDescriptor.GetConverter(type); 
     return converter.ConvertFrom(s.SettingValue); 
    } 

Вот пример данных в таблице sql.

guid  SettingName   SettingValue SettingType 
95473a84 SMCreateTime   00:12:00  System.TimeSpan 
81037bdc SMCreateEnabled  True   System.Boolean 
99e06df7 SMUsername    Username  System.String 
+0

Отличное решение! Раньше я никогда этого не использовал. Если бы я только знал об этом, прежде чем я построил свое собственное решение, это спасло бы меня некоторое время. –

0

Проблема, с которой вы сталкиваетесь, заключается не в том, что вы не возвращаете данные, а в том, что PropertyInfo имеет значение null.

Линия:

PropertyInfo propertyInfo = s.GetType().GetProperty(s.SettingType); 

ли на самом деле пытается найти свойство «TimeSpan» на объекте SettingDataValue (используя строку данных, которые были указаны). Поскольку это свойство не существует, оно возвращает null. Затем вы пытаетесь установить значение свойства и получить исключение нулевой ссылки.

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

public object Value 
{ 
    get 
    { 
     return SomeMethodThatConvertsYourStringValueToTarget(); 
    } 
} 

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

private object SomeMethodThatConvertsYourStringValueToTarget(); 
{ 
    switch (SettingType) 
    { 
     case "TimeSpan": 
      //conversion code 
      break; 
    } 
} 

Затем измените метод getSettingsFromDb для возврата объекта вместо динамического. Затем вы можете использовать его как:

TimeSpan ts = (TimeSpan) getSettingsFromDb ("SMTimeStart");

В качестве альтернативы вы можете создать метод для каждого типа данных, чтобы не использовать его при его использовании. Таким образом, вы можете использовать его как:

TimeSpan ts = getTimeStampFromDb ("SMTimeStart");

+0

Давид, я ценю ваш ответ, но мне было нужно что-то, что не требовало написать специальный метод, основанный на каждом случае. Ты поместил меня на запись, потому что по какой-то причине меня повесили на размышления. Взгляните на мое решение ниже и дайте мне знать, что вы думаете. –