【问题标题】:Web Api 2.2 - OData is expanding data without $expand parameterWeb Api 2.2 - OData 正在扩展没有 $expand 参数的数据
【发布时间】:2017-06-30 14:04:04
【问题描述】:

根据文档,OData 应该只返回直接查询的实体,除非传递 $expand 来获取相关实体。但这不是它对我的表现。我有一个端点来获取子实体,但即使 $expand 没有传递,它仍然会返回父数据。

如何阻止这种情况发生?我想要记录的行为:

/api/Child?$top=10 返回前 10 个子实体

/api/Child?$top=10&$expand=Parent 返回前 10 个子实体并包含父数据。

我在 .NET 4.6.1、Visual Studio 2015 上使用 Web Api 2.2 和 EntityFramework 6.1.3。

控制器:

[ResponseType(typeof(IQueryable<Child>))]
[EnableQuery]
public IQueryable<Child> Get()
{
    return _repo.GetChildren();
}

数据层:

public IQueryable<Child> GetChildren()
{
    return Context.Childs;
}

型号:

public partial class Child
{
    public int ChildId { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public virtual Parent Parent { get; set; }
}

点击端点 /api/Child?$top=1 返回:

"value": [
    {
      "ChildId": 1,
      "Name": "(child name)",
      "ParentId": 3387,
      "Parent": {
         "ParentId": 3387,
         "ParentName": "(parent name)",
         "DateUpdated": "2017-06-23T11:42:06.013+01:00"
      }
    }
]

除非我要求,否则如何阻止它返回父数据?

【问题讨论】:

  • 我想我已经弄清楚了这里的行为模式,但没有更明智的方法来阻止它这样做。 Parent 类没有端点。如果没有定义端点,OData 似乎会扩展所有相关实体。如果我添加 ParentController 并将 builder.EntitySet 添加到 WebApiConfig,Child 将不再返回 Parent 数据而不被要求。如果我从 WebApiConfig 中删除 builder.EntitySet,Child 会再次返回 Parent 数据。所以我可以重现这个问题,但我没有设法阻止它。
  • 我尝试使用 .HasOptional(c => c.Parent),它确实删除了父数据,但是如果我尝试通过 /Child(1)/Parent 获取父数据,我得到406 错误。我可以看到代码在 ChildController.GetParentFromChild() 中遇到了断点,这是导航属性的命名约定,但是在返回 IQuerable 后,响应变成了 406 Not Acceptable。

标签: .net entity-framework asp.net-web-api2 odata


【解决方案1】:

首先让我们看看 DbContext 正在生成的 SQL。

为此,只需在“上下文”构造函数中添加以下行:

this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

如果您的 SQL 包含“父”表的“JOIN”,那么您的实体正在被急切加载...我会检查您的数据层或您的上下文以查看您是否可能包含父实体。

... Context.Child.Include(s => s.Parent)

我重新创建了您的场景,是的,它应该可以按照您的预期工作。

【讨论】:

  • 我记录了SQL,实际上是懒惰地一一加载每个Parent实体。
  • 奇怪的是,我尝试将 .Include() 添加到另一个实体 - 为此,OData 没有返回包含的实体。它似乎在做与我认为应该做的事情完全相反的事情。我今天早上也遇到了 EntityFramework 的奇怪问题,我在 2 个不可为空的列之间添加了一个关联(在数据库和 EF 中它们都不是空的),而 EF 编译失败,因为它说可以为空依赖项。我不知道它有什么问题。
  • 通过进入存储库代码,看起来可能是 OData 问题,因为在创建查询对象时,它具有正确的连接(或没有连接),但是当SQL实际运行时,它变成了错误的查询。
猜你喜欢
  • 2015-01-03
  • 1970-01-01
  • 2015-04-13
  • 2015-05-20
  • 2014-10-08
  • 2015-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多