我有一个应用程序,多个商店将共享数据。有一个选项表定义了各种程序选项。我有一个定义值类型、int、bool、Guid、string 等的 varchar 列。有两个表定义选项值,一个用于系统范围的选项,一个用于本地选项。基本选项表定义是否可以在系统范围选项之前选择本地选项。 Shop 和 Global option 表的结构基本相同,只是 ShopOption 表具有记录所属商店的 ShopId FK。这些表中的每一个都将选项值存储为 varchar,尽管字符串可能表示整数、Guid、bool,或者实际上可能是一个字符串。我需要显示一个表单,其中包含一个用于本地选项的选项卡、一个用于全局选项的选项卡以及一个用于指定商店是否可以覆盖全局选项的选项卡。我做的不对是获取一个选项实体并获取应有类型的值。
例如:
GetOption(SessionTimeout)应该返回一个Option实体,值应该是一个整数类型。
GetOption(DefaultCustomer) 应该返回一个 Option 实体,值应该是一个 Guid 类型。
我正在使用设计模式寻找答案,并认为工厂模式可能是我想要的,但我就是没有得到它。
最佳答案
潜在的问题是您正在遭受 inner platform effect 的困扰,您试图通过将应该不同的类型化列存储为 varchar
来在数据库中创建一个数据库。
您已经赋予了自己在运行时添加选项的能力。但是,如果应用程序不理解它们,它们就没有任何意义,并且您无法在运行时添加这种理解。选项集必须在设计时已知,这意味着模式可以在设计时已知,这意味着您无需将结构抽象为 varchar
值。
创建一个表,其中包含代表您的每个选项的列,并使用正常的 ORM 实践来声明它映射到的数据类型。
抽象实际上并没有给你买任何东西。
根据 OP 的评论进行编辑:
要实现级联设置,您可以制作一个OptionSet
表,每个选项都有一列。只有一行,代表全局集。对于每个可以被经理覆盖的选项,将一个可为空的列添加到 Store
表。
然后您可以使用一个方法来请求 Store
合并有效选项:
public class Store
{
public virtual bool? AllowSavePasswords { get; set; }
public virtual OptionSet GetEffectiveOptions(OptionSet globalOptions)
{
return new OptionSet
{
AllowSavePasswords = this.AllowSavePasswords ?? globalOptions.AllowSavePasswords,
LoginTimeout = globalOptions.LoginTimeout
// Repeat pattern for all options
}
}
}
如您所见,这允许所有内容都保持强类型,同时解决了无法覆盖的选项问题。它还通过在 Store
表中指定所有选项(反射(reflect)它们的范围)并使它们可为空(反射(reflect)它们的可选性质)来表达可以覆盖哪些选项的意图。
好的部分是没有新的技术可以学习或“魔法”来实现(除非你没有看到 ?? operator ,它相当于 T-SQL 的 COALESCE
函数).
关于c# - 如何实现具有多种返回类型的选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1977011/