【问题标题】:Storing of settings without database不使用数据库存储设置
【发布时间】:2010-12-01 11:10:00
【问题描述】:

我需要将列/数据类型对的列表存储为应用设置。 列/数据类型对的数量约为 50 - 100,但可能更多。 由于客户要求,我无法将这些存储在表格中。 将有用户界面供用户从列表中添加/编辑/删除。

我最初想在 app.config 中存储一个分隔字符串。 存储在 app.config 中的键中的字符串大小是否有实际限制?

有没有更好的办法?

[根据 sanjii 的评论编辑] 是否可以使用数据集读取/写入 xml 文件?

【问题讨论】:

    标签: c# .net app-config


    【解决方案1】:

    由于这些设置会在您的应用程序启动时加载到内存中,因此您可以安全地将值存储在适合内存的配置中。换句话说,就好像您在 C# 中对字符串进行了硬编码(就内存利用率而言)。

    作为替代方案,您的客户义务是否会排除使用 SQLite 之类的内容?

    SQLite 是一个软件库, 实现了一个独立的, 无服务器,零配置, 事务性 SQL 数据库引擎。 SQLite 是部署最广泛的 SQL 世界上的数据库引擎。这 SQLite 的源代码在 公共领域。

    【讨论】:

      【解决方案2】:

      我会将它们存储在一个 XML 文件中。您可以使用 XML 序列化或只是一个数据集。

      DSUser ds = new DSUser();
      ds.ReadXml(fileName);
      
      ds.AcceptChanges();
      ds.WriteXml(fileName);
      

      【讨论】:

      • +1 这似乎是 XML 的完美场景,尽管我更喜欢纯 XML 序列化而不是 DataSet 选项。
      • 我和@santiiiii 在一起(希望那里有足够的 i),但我这样做是为了进行一些快速而肮脏的序列化,而且效果很好。
      • @callisto:就像上面发布的@Arthur 一样简单,其中“文件名”是所述 XML 文件的路径!
      • 是的 - 这确实是一个简单任务的快速解决方案。我只需要存储多达 10 个用户。当它变得更复杂时,我也更喜欢 XML 序列化方法。
      【解决方案3】:

      暂时不要放弃 app.config/app-settings。

      为了在我们的应用程序配置中存储更复杂的数据结构,我们采用了两种方法:如果我们尝试存储的数据结构可以序列化到 XML 或从 XML 序列化,我们将其作为字符串存储在应用程序设置中.另一种方法是实现TypeConverter,它将您的数据结构转换为字符串并返回。

      这是一个裁剪的示例:

      [TypeConverter(typeof(FormStateConverter))]
      public class FormState : INotifyPropertyChanged, IDisposable {
         private Size _Size = Size.Empty;
         private Point _Location = Point.Empty;
         private FormWindowState _WindowState = FormWindowState.Normal;
      
         public FormState(Form form) { BindTo(form); }
      
         internal FormState(Size size, Point location, FormWindowState state) {
            _Size = size;
            _Location = location;
            _WindowState = state;
         }
      
         // lotsa other code...
      }
      
      internal class FormStateConverter : ExpandableObjectConverter {
         public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
            if (destinationType == typeof(string)) {
               return true;
            } else {
               return base.CanConvertFrom(context, destinationType);
            }
         }
      
         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
            if (sourceType == typeof(string)) {
               return true;
            } else {
               return base.CanConvertFrom(context, sourceType);
            }
         }
      
         // This converts a FormState to a string, we're just making a CSV string here...
         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
            if (destinationType == typeof(String)) {
               FormState formState = (FormState)value;
               string converted = string.Format("{0},{1},{2},{3},{4}", formState.Size.Height, formState.Size.Width,
                  formState.Location.X, formState.Location.Y, formState.WindowState.ToString());
               return converted;
            }
      
            return base.ConvertTo(context, culture, value, destinationType);
         }
      
         // This converts a string back into a FormState instance.
         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
            if (value is string) {
               string formStateString = (string)value;
               string[] parts = formStateString.Split(','); // split the CSV string
      
               if (parts != null && parts.Length == 5) { // attempt some error checking
                  Size size = new Size();
                  Point location = new Point();
                  FormWindowState state = FormWindowState.Normal;
      
                  int tmp;
                  size.Height = (Int32.TryParse(parts[0], out tmp)) ? tmp : 0;
                  size.Width = (Int32.TryParse(parts[1], out tmp)) ? tmp : 0;
                  location.X = (Int32.TryParse(parts[2], out tmp)) ? tmp : 0;
                  location.Y = (Int32.TryParse(parts[3], out tmp)) ? tmp : 0;
      
                  if (string.Equals(parts[4], "maximized", StringComparison.OrdinalIgnoreCase)) {
                     state = FormWindowState.Maximized;
                  } else if (string.Equals(parts[4], "minimized", StringComparison.OrdinalIgnoreCase)) {
                     state = FormWindowState.Minimized;
                  } else {
                     state = FormWindowState.Normal;
                  }
      
                  return new FormState(size, location, state);
               }
            }
      
            return base.ConvertFrom(context, culture, value);
         }
      }
      

      在实现类型转换器并使用TypeConverterAttribute 赋予我们的FormState 数据类型后,FormState 类型将显示在 Visual Studio 的设置设计器中:

      【讨论】:

      • 注意:可以创建使用更复杂的分层结构的自定义 appconfig 部分。
      • 你是对的。不幸的是,我只是简要地读过这方面的内容,还没有机会实现任何东西。有什么好的链接可以保留以备将来阅读?
      【解决方案4】:

      我也投票支持基于 XML 的设置解决方案。你可以在DotNetBlogEngineSource Code 找到一个很好的例子。

      它基于一个基本的 Xml 文件、一个单例设置类和一个用于读写相关内容的 SettingsProvider。 正确实施后,您所要做的就是调用设置类的实例;

      ApplicationSettings.Instance.Name = "MyApplicationName";
      ApplicationSettings.Instance.Description = "It's an awesome application";
      ApplicationSettings.Instance.Theme = "LoveThemeofMGS";
      ApplicationSettings.Instance.Save();
      
      testlabel.Text = ApplicationSettings.Instance.Name;
      testlabel2.Text = ApplicationSettings.Instance.Description;
      

      我个人在我的大多数 Web 项目中都使用它,这是一个简单干净的解决方案。

      【讨论】:

        【解决方案5】:

        1) 像大多数回答您的问题的人一样 - 我认为使用某种基于 XML 的配置将是最方便的。我认为 appconfig 应该足够了。这取决于您是否只需要 Properties.Settings.Default,或者您可能只需要使用 ConfigurationManager 来完成一些更复杂的任务。

        2) 如果您想使用类型化数据集,您应该使用 xsd.exe 工具(在 Visual Studio Packaga 和 .Net Framework SDK 中都可用)。这个小工具允许您从 xml 文件生成模式,并从模式中生成代码或类型化的数据集。真的很有用。

        3) 如果您考虑使用内存数据库...也许使用 Microsoft 的 SQL Compact 服务器而不是 SQLite 会更好? (注意有一些problems with dealing with date fields while using SQLite

        【讨论】:

          猜你喜欢
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 2011-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多