【问题标题】:OData using $expand breaks cast operation due to wrapper由于包装器,使用 $expand 的 OData 会中断强制转换操作
【发布时间】:2014-01-25 14:30:05
【问题描述】:

我遇到了与here: 相同的问题

但是,答案对我来说还不够。首先,我一生都无法在 OData 5.0.0(不是 RC1)中找到 HierarchyNodeExpressionVisitor(或者任何地方,尝试谷歌搜索)。

第二,即使我确实发现它返回IHttpActionResult 不够好,我需要返回一个键入的PageResult<MyViewModel>

声明的返回IHttpActionResult 的理由是“处理结果可能不再是IQueryable<MyEntity> 的事实。”一旦使用了 $expand 运算符。

但这对我来说没有意义,因为我认为 $expand 运算符用于在实体上包含导航属性,就像服务器端 Include(e => e.RelatedProperty) 一样。至少在我的情况下,我只包含实体上已经存在的属性,所以我不必担心它“可能是其他东西”。

但是,当使用$expand=Department 时,我不能将Cast<>() 转换为实体类型,因为它不能将SelectAllAndExpand<MyEntity> 转换为MyEntity。

如何将展开“展开”回原始实体以便进行投影?

public PageResult<DateSnippetWithDepartmentsViewModel> GetDatesWithDepartments(ODataQueryOptions<DateSnippet> options)
{
    IQueryable query = options.ApplyTo(_context.DateSnippets, new ODataQuerySettings());;

    //Exception when using $expand.. cannot cast SelectAllAndExpand<DateSnippet> to DateSnippet
    List<DateSnippet> dateSnippets = query.Cast<DateSnippet>().ToList();

    var dateSnippetsViewModels = (from d in dateSnippets
                                    select new DateSnippetWithDepartmentsViewModel
                                    {
                                        ...
                                    });

    var result = new PageResult<DateSnippetWithDepartmentsViewModel>(
            dateSnippetsViewModels as IEnumerable<DateSnippetWithDepartmentsViewModel>,
            Request.GetNextPageLink(),
            Request.GetInlineCount());

    return result;
}

【问题讨论】:

  • 你不能。不过,您可能想看看这个。 beyondtheduck.com/…
  • 你的 DateSnippetWithDepartmentsViewModel 和 DateSnippets 是什么样子的?
  • 当你扩展一个类型时,你需要有一个虚拟集合(通常是顶层对象中的IEnumberable&lt;Type&gt;或SingleResult&lt;Type&gt;属性。然后扩展将应用关系foreign_key数据和你的原始对象将使用关系数据“扩展”它的属性。当然,这完全取决于 OData 的版本,以及它是独立还是 WCF 服务实例。有时不同平台的规则不同。
  • 感谢您的评论。从那以后,我们放弃了 OData,因为它真正为我们做的只是允许我们创建更少的 API 端点,但代价是将更多的数据处理转移到客户端。这种认识和缺乏支持使我们坚持使用普通的 Web api 端点。

标签: c# asp.net-web-api odata


【解决方案1】:

试试这个。希望应该可以工作,当我们到达枚举器时,结果应该是DateSnippet。您之前所做的是尝试在 Linq 表达式树中进行投射。我怀疑在 IQueryable Execute 中,它被解析和转换而不是强制转换。

public PageResult<DateSnippetWithDepartmentsViewModel> GetDatesWithDepartments(ODataQueryOptions<DateSnippet> options)
{
    IQueryable query = options.ApplyTo(_context.DateSnippets, new ODataQuerySettings());;

    List<DateSnippet> dateSnippets = new List<DateSnippet>();
    foreach(DateSnippet item in query)
    {
        dateSnippets.Add(item);
    }

    var dateSnippetsViewModels = (from d in dateSnippets
                                    select new DateSnippetWithDepartmentsViewModel
                                    {
                                        ...
                                    });

    var result = new PageResult<DateSnippetWithDepartmentsViewModel>(
            dateSnippetsViewModels as IEnumerable<DateSnippetWithDepartmentsViewModel>,
            Request.GetNextPageLink(),
            Request.GetInlineCount());

    return result;
}

【讨论】:

  • 一旦使用 $expand 参数,这对我来说不适用于 Microsoft.OData.Core.7.0.0。根据MSDN IQueryable 接口旨在由查询提供者实现。它只应该由也实现 IQueryable 的提供者实现。 显然这里不是这种情况,因为对 IQueryable 的“查询”转换失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多