我们有一个包含不同组件的软件套件和大多数这些组件使用的SQL Server数据库。
假设我们有一个表Configuration
,其中包含两列[Name]
和[Value]
。该表包含我们的数据库方案版本(Name='Version', Value='1.0'
)。
然后我们有一个包含Customer
和ID
列的表Name
。
因此,此表上的linq-to-sql查询类看起来像这样:
[Table(Name="Customer")]
public class Customer
{
[Column]
public long ID {get; private set;}
[Column]
public string Name {get; set; }
}
对于我们的下一个发行版,我们需要更改此Customer
表并添加一列Address
。当我们安装这个新方案时,我们将Configuration
表中的版本值设置为1.1,这样我们就可以确定安装了哪个版本。
我们的很多客户都在等待这个新版本的组件,因为它有一个错误修正,但他们实际上并不需要新的数据库架构(原因并不重要,让我们假设我们的软件需要向后兼容旧的db模式)。
所以我的问题是,有没有最佳实践技术来处理这种情况?
如果我将新列添加到Customer
类,如
[Column]
public string Address {get; set;}
我无法将此类用于对具有1.0模式的数据库的请求(因为缺少列的SqlException)。如果我创建一个新类(派生,或使用接口或任何其他),我必须处理不同的模式版本的不同类型。当然Table<Customer10>
永远不会转换为Table<Customer11>
,无论Customer10
和Customer11
之间的继承关系是什么。所以直到现在我还没有找到一种方法以透明的方式将这些问题封装在我的DataContext派生中:
public class MyDataContext : DataContext
{
public Table<Customer> Customers
{
get
{
// this won't compile, no matter how Customer10 and Customer11 are related
return version > 10
? GetTable<Customer11>()
: GetTable<Customer10>();
}
}
}
我还尝试了inheritance hierarchies和discriminators,但由于该版本不是Customer
的列,因此这似乎不起作用。
我想找到一个解决方案,我可以在每个表中使用一种类型用于不同的模式,如果已安装的数据库方案不支持删除或添加的列,则采用默认值。