您将如何在 C# 项目中存储表格常量数据?
我目前正在为 CAD 风格软件编写插件。 该插件根据从 CAD 模型读取的数据和大量表格查找(想想计算指南中的打印表格)进行计算。 我继承了这个插件,当前的解决方案定义了一个类 Constant
,它有一堆静态结构成员和二维数组。 然后在运行时通过枚举值对这些数组进行索引以查找适当的数据。
我对这个解决方案不太满意,因为 Constant
类中的表示有点难以阅读 - 检索数据时使用的枚举值在编辑时当然不可见 em> 数据(尽管这只发生在手动且很少的情况下)。
我不想将数据库(和引擎)与小插件捆绑在一起,但想要类似的语义,例如使用 LINQ 选择某些字段匹配的值等。
您对此问题的首选解决方案是什么?
- 您是否使用一堆 XML 文件并在运行时解析它们?
- 您是否使用模板引擎(t4?)在编译时从 XML 文件生成类?
- 您是否在资源中存储数据集的 XML 版本(在运行时读取它们,LINQ to dataset...)
- 您是否只保留
Constants
类,也许向成员添加一些文档(不'不要让我开始了解遗留代码,没有任何评论......)
I am currently writing a plugin to a CAD style software. The plugin does calculations based on data read from the CAD model and a lot of table lookups (think printed tables in a calculation guide). I inherited this plugin and the current solution defines a class Constant
which has a bunch of static struct members and two-dimensional arrays. These arrays are then indexed by enum values at runtime to find the appropriate data.
I'm not too happy with the solution, as the representation in the Constant
class is kind of hard to read - the enum values used when retrieving data are of course not visible when editing the data (although that only ever happens manually and very seldom).
I'd prefer not to bundle a DB (and engine) with a small plugin, but would like similar semantics, for instance using LINQ to select values where some fields match etc.
What is your preferred solution to this problem?
- do you use a bunch of XML files and parse them at runtime?
- do you use a templating engine (t4?) to generate classes from XML files at compile time?
- do you store XML versions of datasets in the resources (read 'em in at runtime, LINQ to dataset...)
- would you just keep the
Constants
class, maybe add some documentation to the members (don't get me started about legacy code with no comments whatsoever...)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我目前正在为性能关键型应用程序执行此操作。 我的方法是序列化平面文件中的数据(作为发布过程的一部分),然后(在启动时)将其反序列化为类模型,从而允许 LINQ 到对象查询。
在大多数情况下,xml 是合理的,但我优先使用自己的二进制序列化器 - 主要是为了速度。
由于常量数据不会更改,因此通常可以将其缓存在您手边的实例中并多次重复使用(而不是每次使用时反序列化)。
澄清一下:要使用的数据存储在标准数据库中(他们擅长此类事情,并且存在许多用于导入/编辑/查询/等的工具)。 作为发布过程的一部分,我将数据从数据库加载到对象模型中(使用相同的类),并将其序列化:
然后我将 data.bin 与应用程序一起发送(好吧,实际上它是单独存储的,但这是旁白……); 在运行时:
请注意,在这种情况下,数据是“冰棒不可变” - 即为了保留“恒定”性质(但同时让它在加载期间编辑数据),我有一个级联
Freeze
在项目上设置标志的方法; 一旦设置此标志,所有编辑(对项目或列表)都会引发异常。 这对运行代码的性能影响为零:因为您希望将其视为常量数据,所以它只进行读取!I'm doing that at the moment for a performance-critical application. The way I do it is by serializing the data in a flat file (as part of my release process), then (at launch) deserializing it into a class model, allowing LINQ-to-Objects querying.
In most scenarios xml would be reasonable, but by preference I'm using my own binary serializer - mainly for speed.
Since the constant data doesn't change, it is usually fine to cache it away in an instance you keep handy and re-use many times (rather than deserialize it per use).
To clarify: the data to use is stored in a standard database (they are good at that type of thing, and lots of tools exist for import / edit / query / etc). As part of my release process, I load the data into the object model (using the same classes) from the database, and serialize it:
then I ship data.bin with the app (well, actually it is stored separately, but that is an aside...); and at runtime:
Note that in this case, the data is "popsicle immutable" - i.e. to preserve the "constant" nature (but while letting it edit the data during load), I have a cascading
Freeze
method that sets a flag on the items; once this flag is set, all edits (to items or to lists) throw an exception. This has zero performance impact or the running code: since you expect to treat it as constant data, it only does reads!除非性能是一个限制,否则我会采用 XML-dataset-in-resources 方法。 它相当明显(因此无论将来谁从您这里获取代码都不会对其外观感到困惑),编辑和访问都很容易,并且不需要以表格 XML 的自定义解析器的形式重新发明轮子数据。
Unless performance is a constraint, I'd go with XML-dataset-in-resources approach. It's fairly obvious (so whoever picks up the code from you in the future won't be befuzzled by its look), it's easy both to edit and to access, and there's no need to reinvent the wheel in form of custom parser of tabular XML data.
如果部署是一个问题,您始终可以在程序集中嵌入一个 XML 文件。 这使您能够保持相同水平的恒定性,因为用户将无法处理数据。
任何文件都可以使用VS作为资源嵌入,只需将文件添加到项目中并选择:Build Action => 来自属性的嵌入资源。
然后在启动时您可以调用:
获取嵌入数据的流。
这种方法的优点是您可以以任何您想要的格式保存常量数据,这将使维护变得更加容易。 启动时,您可以进行所有索引和组织,以便数据具有适当的 API。
If deployment is a concern, you could always embed an XML file inside your assembly. This allows you that same level of constantness, as users will not be able to muck around with the data.
Any file can be embedded as a resource using VS, just add the file to the project and select: Build Action => Embedded Resource from the properties.
Then on startup you could call:
To get a stream to the embedded data.
The advantage of this approach is that you can keep your constant data in whatever format you want, which would make maintenance much easier. On startup you can do all the indexing and organisation so the data has a proper API.
您可以生成
Constant
类。这样您就可以以更方便的方法存储数据,例如 MDB (MS Access) 或 MDF (SQL Express) 文件。 编辑这些文件是用户友好的。
我建议您有一个额外的项目来生成主项目的
Constant
类,并将所有需要的数据作为常量。 额外的项目可以是控制台应用程序。 在主项目中使用预构建事件来执行此控制台应用程序,然后您就拥有了生成的类。You can generate the
Constant
class.This way you can store your data in a more convenient method, such as MDB (MS Access) or MDF (SQL Express) file. Editing these files is user friendly.
I suggest you have an additional project that generates your main project's
Constant
class with all the needed data as constants. The extra project can be a Console Application. Use a pre-build event in the main project to execute this console application, and then you have your generated class.我赞同使用 XML 的建议(无论是否是资源库),但想详细说明一下解析/编辑/处理此场景的问题。
首先,关于与 Pavels 回答是否可以通过 Visual Studio (VS) 中的表编辑器进行可视化编辑 XML:事实上,它曾经在 VS 2003 中使用(参见“图 6.28. XML 文档:数据视图”此处了解其外观),在 VS 2005 中,该功能有所降级(参见例如 Visual Studio 2005 中的 XML 外观与 Visual Studio 2003)和 VS 2008 中最终被删除(参见例如 Visual Studio 2008 中缺少 XML 数据编辑器),这是非常不幸的,因为它有它的用途,并且可能对你也有帮助。 同样的(可能相关的)命运也适用于 XML 模式设计器,它至少会在 VS 2010 中得到替代,但还不知道新的 XML 数据视图。
回到您原来的问题:根据您的要求,您可以提供专用的 XML 记事本 2007。
然而,拥有 XML 模式最重要的好处是,它允许通过工具自动使用,特别是您可以生成两者,普通的旧 .NET 类和/或 >通过 Microsoft 的 XML 架构定义工具 (Xsd) 获取支持 LINQ 的数据集 .exe)。 (对于众所周知的结构化数据,即由 XML 模式支持,这确实比使用基于 t4 的繁琐的自定义解决方案要好得多。)
当然,首先获取模式并在实践中正确使用它们可能需要一些努力,但这些是值得的恕我直言,对于任何严肃的 XML 相关开发来说,这都是大好时光。
对于手头的任务,您实际上可能已经做得更好了,并且能够从现有类
Constant
中推断 XML 架构,请参阅<的“/t”开关a href="http://msdn.microsoft.com/en-us/library/x6c1kb0s.aspx" rel="nofollow noreferrer">Xsd.exe。 最初的结果可能不完整或不完全足够,但是通过一些预先的重构和/或手动调整,您应该能够很快地得出一个不错的模式。因此,您应该能够像现在一样(大概)使用您的代码库,即您将拥有强类型枚举等,或者您可以根据需要通过启用 LINQ 的数据集切换使用 XML 数据(事实上,你可以同时进行这两项操作)。
I'd second the suggestions to use XML (be it resources base or not) but like to elaborate a little on the questions of parsing/editing/handling this scenario.
First a short note concerning the question related to Pavels answer whether visual editing XML via a table editor in Visual Studio (VS) is possible: it used to be in VS 2003 in fact (see e.g. 'Figure 6.28. XML document: data view' here on how this looked), in VS 2005 the feature got demoted somewhat (see e.g. XML Appearance in Visual Studio 2005 versus Visual Studio 2003) and in VS 2008 finally removed (see e.g. XML Data Editor missing in Visual Studio 2008), which is pretty unfortunate, as it had its uses and might have helped you too here. The same (likely related) fate applies to the XML schema designer, which at least will get a replacement in VS 2010, don't know about a new XML data view yet.
Back to your original question: given your requirements you could supply a dedicated XML schema for your XML files. Once in place, any decent XML editor will be able to supply Intellisense at least (i.e. enum values are visible while editing) and warn you about erroneous data entries too. If editing XML sources this way still feels too 'raw' you might get a more comfortable 'non source' editing via something like XML Notepad 2007.
Yet the most important benefit of having a XML schema is that this allows automated use via tools, in particular you can generate both, plain old .NET classes and/or LINQ enabled datasets from it via Microsofts XML Schema Definition Tool (Xsd.exe). (For well known structured data, i.e. backed by XML schema, this is much preferable than using a tedious custom t4 based solution indeed.)
Granted, getting schemas in the first place and getting them right in practice might require some efforts, but these pay off big time for any serious XML related development, imho.
And for the task at hand you might actually be better of already and be able to infer the XML schema from the existing class
Constant
, see the '/t' switch for Xsd.exe. Likely the initial result might be incomplete or not entirely adequate, but with a bit of up front refactoring and/or manual tweaking you should be able to derive a decent schema pretty quickly.As a result you you should be able to work with your codebase pretty similar like you do now (presumably), i.e. you'll have strongly typed enumerations etc., or you you could switch using the XML data via LINQ enabled datasets as you please (in fact you could do both in parallel).