您的问题并不容易回答。您要求在编程级别上进行数据映射,并且取决于您想要克服/处理多少变化将确定答案必须有多复杂。这也可以看作是模型继承。
首先,edmx 文件对于您想要做的事情毫无用处。它将业务模型与数据模型相结合,这意味着对数据或业务模型的任何更改都会导致文件损坏。
以下两个选项都需要大量工作,并且在大小方面应该被视为一个全新的应用程序。
元数据解决方案
您可能希望考虑在代码中创建元数据/数据层并使用它来更改数据库的外观。
不是通过 ecommerce.edmx 访问模型,而是通过单独的业务/数据层访问它。然后,数据层可以使用动态调用或使用外部首选项文件来保存 sql 访问来创建数据访问/sql。
即
在数据库中创建外部文件、表或代码中的资源,其中包含描述要使用的表的元数据。一个非常简单的解决方案可能如下所示:
MetaTables (id, myTableName, derivedTableName)
Order, "Order", "UserOrder"
Customer, "Customer", "UserCustomer"
MetaAttributes (tableId, id, myAttrName, myAttrType, derivedAttrName, derivedType, etc)
Order, Id, "Id", int, "UserId", guid
Order, Description, "Description", string, "UserDescription", string
Customer, Id, "Id", int, "UserId", guid
MetaRelations ()
etc
然后使用它来动态创建您的查询。如果您这样做,其他人可以使用您的代码,并且只需要使用新映射更新您的元数据文件。只要他们不添加新的必填列。
优势:
- 可以快速处理任何新的数据结构
- 如果需要,可以随时更改数据结构
- 版本无关
弱点:
- 动态创建的查询可能非常慢
- 实现动态数据层需要很长时间
反射解决方案
另一种方法是将数据层存储在单独的程序集中并使用接口引用它。
所有新应用程序需要做的就是用他们的数据层替换您的数据层。
即
public interface IDataLayer
{
public List<IOrder> GetOrderList()
}
// MyDLL1
public class DataLayerImplementationA: IDataLayer
{
public List<IOrder> GetOrderList()
{
// get data from database X, return results
}
}
// MyDLL2
public class DataLayerImplementationB: IDataLayer
{
public List<IOrder> GetOrderList()
{
// get data from database B, return results
}
}
优势:
弱点:
- 需要用新编译的 DLL 覆盖程序集
- 多个 DLL
- 即使是很小的更改也可能需要程序员进行大量编码(或至少剪切和粘贴)
解决方法
如果修改非常简单,您可以编写一个解析器来编辑 edmx 文件中的映射数据。不推荐,因为这可能会导致不稳定。
另一种解决方法可能包括使用数据库视图隐藏更改并将数据更改处理移至数据库。因此,请让旧 edmx 文件查看视图,使用扩展设计的新 edmx 文件查看扩展表。
变通办法就是这样......除了最微不足道的变化之外,它们可能会比它们所值得的更痛苦。
如果您想做一些研究,请查看使用类似术语的文章
- 面向对象的概念
- 抽象数据层
- 模型继承
- 模型控制器视图
狩猎愉快!