我正在维护一个为每个新客户复制粘贴的应用程序( ...是的,我知道)。如果新客户想要一些其他人不需要的新功能,那么他的代码部分只会被更改。该解决方案还包括一种“common.dll”,其中所有代码的放置对所有客户都是相同的。
每个客户的基础MSSQL数据库略有不同。所有表都有或多或少相同的表,但有些客户具有自定义特定功能的附加列或新表。
由于“类型化数据集”(ADO.NET C#2.0)在Visual Studio解决方案中用于每个客户,因此始终存在特定的解决方案(文件),并且其中包含特定类型的数据集(例如“XyDataSet.xsd”) 。在解决方案中,我有帮助类,例如。处理订单。此类中的一个方法可能是“GetOrder(string orderId)”,它使用客户特定的DataSet来检索订单(作为类型化的DataRow)。
如您所见,我为每个客户在每个解决方案中都有“GetOrder”方法,因为订单表中可能没有太多差异,例如可能有其他列。因此,如果需要对一般的“GetOrder”功能进行更改,我必须在所有项目中进行更改,这当然是维护噩梦。
你们有没有人看到这种“架构”可以改进的方式?或者,对于当前潜在的不同数据库方案,在更高的应用程序级别上没有太大的改进?
答案 0 :(得分:3)
完全回答这个问题非常困难,但我会开始这样思考:
数据库级别:
查找添加内容并在单独的表中具有该内容,在该表中指示哪些(来自公共模式)是该行的所有者及其对应的值。 e.g。
订单{OrderID,CustomerID等}(这是所有者表)
OrderExtensions {ExtensionID,ExtensionName,ExtensionValue}(这是订单的扩展表)
OrderExtensionsToCustomers {CustomerID,ExtensionID}(显示哪个扩展程序适用于哪个客户)
数据访问层级:
域模型层级:
UI图层级:
最终图片:
我知道这是一个很长的答案,但我希望这是有道理的: - )
答案 1 :(得分:1)
使用返回无类型数据集的一种常见方法(在共享程序集或服务中)怎么样?然后,您可以在每个解决方案中使用将此方法返回的数据放入类型化数据集的方法。这样,您就可以在一个地方保持与数据库交互的逻辑。
答案 2 :(得分:1)
首先,哎哟。艰难的演出。
你可以做很多事情来建立一个更好的架构 - 这有点取决于你可以花多少时间花在它上面。我建议您阅读Kerievsky的“重构模式”以获取创意。
要回答您的具体问题 - 我会考虑“模板方法”模式。一般来说,您将getOrder定义为一系列步骤,并允许子类根据需要覆盖这些步骤。 http://www.dofactory.com/Patterns/PatternTemplate.aspx
我同意Ole的观点,你需要做的事情之一是理清返回类型 - 这将使重构时的生活变得更加容易。
如果您还没有这样做,我还建议您投资单元测试。
答案 3 :(得分:1)
创建一个类型化数据集,其中包含表的所有常用列,但不包含专用列。在每个表的相应xsd文件中添加一个
<xs:anyAttribute />
这将允许将列加载到未在xsd-dataset中定义的数据表中。
可以通过类型化数据集访问常用列,可以通过名称访问客户特定列,也可以创建 获取额外列的自定义特定扩展方法。
如果vs2008 / vs2010数据集编辑器可以处理这个问题甚至破坏anyAttribute
信息,我不会感到害羞。但dotnet xsd.exe代码生成器支持anyAttribute
,因为dotnet 1.0包括当前的dotnet 4.0