根据this question about dynamically accessing tables的答案,我决定退一步,就更大的图片提出一些建议。
我正在重新审视Windows窗体应用程序的数据库设计,我正在使用ASP.NET重写Web。此外,我已将我们的数据库移植到Sql Server,因此它可以处理更多流量,因为Access数据库已经负担过重。因此,看到SQL Server可以做什么,我一直在重新审视我的数据库设计决策,以及它们对我的用户界面设计的影响。
目前,Windows界面显示最近的代码列表:
02691 AFF1
32391 Lot# 23
等等。
对于每个代码,Productions表中都有一条以:
开头的记录ProductionCode varchar(80),
Template varchar(50),
...
模板表示许多表中的一个,也是模板字段定义中的外键。所有这些信息都用于从代码开始动态构建DataGrid。
有ScoreField表,它代表所有模板中的所有字段,但ProductionCode除外(它们都作为外键)。
ScoreField
Template varchar(50)
Field varchar(50)
Formatting varchar(50) // This is a .NET style formatting string, say 0.00 or ##
...
然后是模板表本身,它们包含一个ProductionCode,每个测试的时间以及测试收集的任何数据。
因此,要动态创建我的数据网格,请从
开始SELECT * FROM ProductionRun WHERE ProductionCode = @Code
实际上,我只得到一个结果,或者如果没有得到结果就中止该过程。
代码是用户选择的代码字符串(使用下拉列表,而不是注入的代码)
然后我这样做:
SELECT * FROM ScoreField WHERE Template = @Template
实际上,在@Template中,返回了ProductionRun的一条记录的Template字段值。
然后我这样做:
SELECT * FROM @Template WHERE ProductionCode = @Code
但实际上,我只是连接了第一部分中的模板名称。
然后我使用ScoreField的结果为每个匹配结果添加列并设置格式,等等。
但是,当然,由于在运行时完成所有操作,我无法使用数据绑定,并且必须以编程方式填写所有数据。
所以,重新访问这个数据库,我正在寻找另一种更好的方法。我在不同的表中有数据,我想对数据应用格式,并且能够在一个界面内完成所有操作,而不是强迫用户猜测他们的数据所在的模板。我希望能够添加模板而不会过多地搞砸系统。
显然,这不是一个简单的编程问题,而是更多关于最佳实践的问题,但我正在寻找一些灵感和/或例子让我开始走另一条道路。
答案 0 :(得分:1)
用户尝试实际看到的数据是什么。最好的办法是首先根据数据库设置数据库,而不是根据最终如何将数据库显示在某个前端。
如果您获得不同格式的不同数据,那么尝试将其全部强制转换为单一类型的结果可能是一个坏主意,这样您就可以使用数据绑定。
答案 1 :(得分:1)
鉴于你上面的评论,我可能会建模如下。
CREATE TABLE dbo.Products (
product_code VARCHAR(10) NOT NULL,
product_name VARCHAR(50) NOT NULL,
CONSTRAINT PK_Products PRIMARY KEY CLUSTERED (product_code)
)
GO
CREATE TABLE dbo.Measurement_Types (
measurement_type_code VARCHAR(10) NOT NULL,
measurement_type_description VARCHAR(255) NOT NULL,
format VARCHAR(20) NOT NULL,
CONSTRAINT PK_Measurement_Types PRIMARY KEY CLUSTERED (measurement_type_code)
)
GO
CREATE TABLE dbo.Measurements (
product_code VARCHAR(10) NOT NULL,
measurement_type_code VARCHAR(10) NOT NULL,
measurement_value DECIMAL(10, 4) NOT NULL,
CONSTRAINT PK_Measurements PRIMARY KEY CLUSTERED (product_code, measurement_type_code),
CONSTRAINT FK_Measurements_Products FOREIGN KEY (product_code) REFERENCES dbo.Products (product_code),
CONSTRAINT FK_Measurements_Measurement_Types FOREIGN KEY (measurement_type_code) REFERENCES dbo.Measurement_Types (measurement_type_code)
)
GO
如果测量值是历史值,则添加DATETIME列。此外,不知道具体数据类型显然可能会改变。
由于每种产品类型都可以进行不同数量的测量,因此您可能会使用该格式动态构建数据网格,并根据需要添加列。我知道你说你想要避免这种情况,但是制作一个通用应用程序需要付出代价(我知道你的应用程序并不是完全通用的,但是你试图创建应用程序时更开放或“自由形式” ,优化越困难,你需要做出更多妥协。
一种可能性是创建一个具有您希望支持的最大列数的数据网格,然后使用存储过程或视图返回该列数,而不管实际测量是否可用于产品类别。然后,您仍然可以绑定到该SP或视图,只需隐藏运行时未使用的列。