首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

OData包含
EN

Stack Overflow用户
提问于 2019-03-14 21:14:22
回答 1查看 506关注 0票数 2

我刚刚了解到,使用Contained属性,我可以定义一个包含的集合。这意味着不能再从我的根oData系统访问该集合。好吧,好吧,但这是我的模型:

我有一个用户的地址,该用户有发票,每张发票可以有一个或两个地址从用户。

我应该在哪个集合上添加包含的属性?

EN

回答 1

Stack Overflow用户

发布于 2019-04-15 04:31:55

这个问题的答案完全取决于您的域模型。我给出的建议是谨慎使用OData容器。只有当您标记为包含实体的实体不能存在于父实体的上下文之外时,使用它才真正有意义。由于这个限制,我认为OData包含的用例很少,而且介于两者之间。与单独的控制器相比,它的优势在于,从架构的角度来看,它更有意义。然而,您的控制器变得更加臃肿,维护方法上的ODataRouteAttributes变得更加繁重。使用基于约定的路由时不需要的东西。

the guide to set up OData containment上的示例在一定程度上解释了这一点。它在你为什么要使用它方面有点欠缺。请注意,PaymentInstrument实体没有指向Account的外键。这意味着没有存储PaymentInstrument信息的单独的表。相反,它直接存储在Account记录中。但是仍然被定义为Collection<T>,所以它可能被存储为JSON或跨多列存储。情况可能不一定是这样,但从代码的角度来看,数据库可能是这样的。

为了进一步解释OData包含,我们假设我们有下面的域模型。

代码语言:javascript
运行
复制
public class HttpRequest
{
    public int Id { get; set; }

    public DateTime CreatedOn { get; set; }

    public string CreatedBy { get; set; }

    public virtual HttpResponse HttpResponse { get; set; }
}

public class HttpResponse
{
    public string Content { get; set; }

    public DateTime CreatedOn { get; set; }
}

如您所见,HttpResponse类没有HttpRequest的导航属性。因此,调用GET odata/HttpResponses是没有意义的,因为我们将获得所有的HttpResponses,而不是它们所链接的HttpRequest。换句话说,如果没有上下文,即为其生成的HttpRequestHttpResponse类将毫无用处。

HttpRequest上下文之外没有任何意义的HttpResponse类使其成为OData容器的完美候选者。这两个类甚至可以保存在数据库中的同一记录中。而且因为在不指定HttpResponse所属的HttpRequest的id的情况下无法执行GET/POST/PUT/DELETE,所以HttpResponse类拥有自己的控制器是没有意义的。

现在,回到您的用例。我可以看到两个可能的领域模型。

  1. 实体UserUserAddressInvoiceInvoiceAddress.

在第一个选项中,每个单独的实体都有它们自己的指定地址实体。在这里,使用这样的设计是有意义的,因为地址实体不存在于它们各自的父实体之外。UserAddress始终链接到UserInvoiceAddress始终链接到Invoice。获取单个UserAddress实体意义不大,因为使用此域模型时不应该关心单个地址在哪里。相反,重点更多地放在这个单一User的持久地址是什么上。如果不指定现有的User,也无法创建UserAddressUserAddress实体完全依赖于User实体。

  1. 实体UserInvoiceTypedAddressAddress.

在第二个选项中,Address实体是独立的。它独立于其他实体存在。由于地址归结为这个星球上的唯一位置,因此它只保存一次。然后,其他实体通过TypedAddress实体链接到Address实体,其中它们指定它相对于链接到它的实体的地址类型。使用此域模型获取单个Address非常有意义。通过请求GET odata/Addresses,可以轻松地检索整个公司的地址簿。这就是OData限制没有意义的地方。

请注意,可以使用ODataConventionModelBuilder来配置包含。因为您不需要将ContainedAttribute添加到类中,所以这样做的好处是不会因为引用OData库而污染您的数据层。我会推荐这种方法。在你的情况下,我希望有下面的配置。

代码语言:javascript
运行
复制
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder
    .EntityType<User>()
    .ContainsMany(user => user.UserAddresses);
modelBuilder
    .EntityType<Invoice>()
    .ContainsMany(invoice => invoice.InvoiceAddresses);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55163519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档