我的 EF 数据模型中有一些实体,其中实体的键是两列的组合。
虚构(但相当接近)的例子......三个实体
Patients
PatientID (PK)
PatientName, etc
Identifiers
PatientID (PK)
IdentifierTypeID (PK)
Code
StartDate, etc
IdentifierTypes
IdentifierTypeID (PK)
Description
Identifiers 表有一个复合键。基本上是患者和 IdentifierTypes 之间的多对多,但数据在连接表上。这应该无关紧要,但如果确实如此,ID 就是 GUID(SQL Server 中的唯一标识符)。
我可以稍微弯曲我的数据库以在标识符中创建一个新列,例如“IdentifierID”,它可能是主键,但我们有一个遗留代码库,如果可以避免的话,我宁愿不修改它。
我可以看到几种避免修改表的解决方案,尽管我不确定在 WebAPI 中是否真的可行
a)在数据库中创建一个视图并将其作为我的实体的基础。视图的形式为
select
*,
IdentifierID = cast( PatientID as varchar(50) ) + '_' + cast( IdentifierTypeID as varchar(50) )
from Identifiers
这有一个问题是从实体框架中寻找 IdentifierID 会很慢。我可以用我想的索引视图来纠正这个问题。
b) 与 (a) 相同,但在我的控制器的 [Queryable] Get() 方法中,我改为使用 ODataQueryOptions 和一些表达式解析魔法(根本没有经验)来查看我们是否在 IdentifierID 上进行过滤,如果是的话,将其拆分为 PatientID 和 IdentifierTypeID 上的过滤器
c) 我保持原样,并在 WebAPI OData 堆栈中发现了一些对 Tuple 作为实体键的未知支持。那太棒了 :) 我继承自 EntitySetController<>,所以看起来我继承自 EntitySetController>
d) (c) 的一些混合,虽然不那么聪明,但仍能达到相同的结果
在 OData 规范中似乎有复合键,因为 StackOverflow 上的另一个问题说明了如何在 OData 中处理这样的实体(使用 WCF 数据服务)。如何处理 OData Url 中使用复合身份密钥的实体?
我不介意使用每晚构建,甚至使用 ASP.Net 源代码——我已经在周末单步执行 OData 请求以解决另一个问题(我的错)在查询字符串中格式化 GUID:P 我希望有人已经投资理解这一点的时间,我可以避免另一天在框架源代码中遇到断点。
谢谢你的帮助,伊恩