【发布时间】:2015-12-15 18:27:16
【问题描述】:
我有一个包含 Web API OData 服务层的多租户应用程序。我有一个支持自定义字段的新要求,这对于每个租户都是唯一的,并且向我的表中添加通用的“customfield01”、“customfield02”列不够灵活。
我已经探索了多种方法来在后端描述和持久化自定义数据,但更具挑战性的部分似乎是扩展我的 odata 服务以包含每个租户不同的自定义字段。
以下链接描述了带有 Web API 的 odata v4 中的“开放类型”:
示例代码运行良好,并提供了我在实体上需要的动态属性行为。但是,该代码仅在后端使用硬编码的值列表。完全不清楚如何从实体框架数据上下文填充实体。
起初,对于每个租户来说,这似乎就像在数据库中拥有一个特定于租户的视图一样简单,但问题是扩展属性确实需要从列中“反透视”到 key-值对。因此,我想知道“扩展”属性是否需要一个单独的实体。所以,我的 POCO 可以有这样的东西:
public class Item
{
[Key]
public Guid ItemId { get; set; }
public Guid TenantId { get; set; }
// navigation property for the extension entity
public virtual ItemExtension ItemExtension { get; set; }
}
public class ItemExtension
{
[Key]
public Guid ItemId { get; set; }
// dynamic properties for the open type
public IDictionary<string, object> DynamicProperties { get; set; }}
}
但是,问题又变成了如何用我的数据上下文中的数据填充这些对象。再一次,我认为我可以对列进行反透视,但这不起作用,因为我可以为每个动态属性拥有不同的数据类型(这对我很重要)。
所以,我真的有几个问题:
- 上面的 POCO 模型对我想要完成的工作有意义吗?
- 包含所有 HTTP 动词(GET、POST、PUT、PATCH、DELETE)的 ItemExtension 的 ItemController 代码应该是什么样子
- 我的数据上下文应该为 ItemExtension 提供什么以允许它访问后端的扩展列
- 应如何将扩展列保留在后端以支持这一点。
就我所尝试的而言 - 很多东西都不起作用,但我已经解决了以下问题(假设没有更好的方法):
每个“可扩展”实体的基本 POCO,具有单独的“扩展” 每个实体(如上面的模型)
在后端,由于我需要无限的灵活性和强大的数据类型,我计划为每个租户/实体组合创建一个单独的扩展表(将命名为 [TenantId].[ItemExtension] 与每一列根据需要命名和键入)。
我缺少的是数据和模型之间的所有内容。任何帮助将不胜感激。
【问题讨论】:
-
很好的问题,我现在真的很困惑,有没有人成功使用带有 EF6 后端的 OData v4 开放类型?注意:不是 NHibernate...寻找 EF6 解决方案我将首先采用代码或模型
-
我目前正在做的是使用 EF 上下文的连接来执行存储过程。然后,我必须遍历数据以创建开放类型。它有效,我只是希望在将数据返回给调用者之前不必“处理”控制器中的数据。
-
原来我被困在一个与此略有不同的问题上,除了运行时尝试应用查询选项时任何未指定 $select 语句的 GET 调用都失败之外,我一切正常传入的...我的问题是,当没有指定 $select 时,这与 SQL select * 相同,只有运行时将所有列注入到选择参数中,包括 DynamicProperties。必须覆盖 EnableQuery...我不确定您是否可以避免不得不“处理”数据,否则我们不妨将自定义属性硬编码到 DTO 中。
标签: c# asp.net entity-framework asp.net-web-api