OData“序列包含多个元素”错误

时间:2013-02-07 03:41:12

标签: asp.net-web-api odata

  

序列包含多个元素   在System.Linq.Enumerable.SingleOrDefault [TSource](IEnumerable`1 source)at at   System.Web.Http.OData.Builder.ODataConventionModelBuilder.RemoveBaseTypeProperties(EntityTypeConfiguration derivedEntity,EntityTypeConfiguration baseEntity)     在System.Web.Http.OData.Builder.ODataConventionModelBuilder.DiscoverInheritanceRelationships()......

这是我的绑定代码:

var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<PeopleDto>("People");

这是我的控制器代码:

[Queryable]
public IEnumerable<PeopleDto> Get(
        [FromUri] Credentials credentials, 
        ODataQueryOptions<PeopleDto> options, 
        int departmentId,
        DetailLevel detail = DetailLevel.Low)
{
    var count = _repository.Filter(x => x.DepartmentId == departmentId && x.Active);
    options.ApplyTo(count);
    int total = count.Count();

    switch (detail)
    {
        case DetailLevel.Low:
            return new Paginable<PeopleDto>(GetMyPeopleLo(departmentId, options), total);
        // [...]
    }
}

Paginable<T>实施IEnumerable<T>。并且GetMyPeopleLo()(不是真实姓名)方法将选项应用于其他查询。 (我不再需要其他查询了,因为我已经移动了分页代码的位置,但我还没有重构那个部分。)

这是oData的预发布版本存在问题吗?

更新:如果我注释掉Queryable属性,它似乎可以正常工作,但是当选项应用于{{{}时,我在查询字符串中指定的任何过滤器都不会被实际应用1}}查询。

3 个答案:

答案 0 :(得分:2)

有几件事情在这里跳出来:

  • 您不应该使用[可查询]和ODataQueryOptions。它们用于做同样的事情。 在这种情况下,ODataQueryOptions似乎更合适,所以你应该删除[Queryable]。
  • 您没有使用查询结果。而不是这个

    var count = _repository.Filter(x => x.DepartmentId == departmentId && x.Active);
    options.ApplyTo(count);
    int total = count.Count();
    

    你应该这样写:

    var count = _repository.Filter(x => x.DepartmentId == departmentId && x.Active);
    var queryResults = options.ApplyTo(count) as IQueryable<PeopleDto>;
    int total = queryResults.Count();
    

    这样你的总数就会考虑OData查询选项。

  • 考虑使用PageResult<T>而不是Paginable,因为OData格式化程序将计算并将其正确插入到OData Feed中。

答案 1 :(得分:2)

我在以下两种情况下看到了这个错误。

  1. 阴影实体成员 - 派生自阴影而非覆盖的实体的成员(请参阅此discussion of the difference)。交换到覆盖解决了这里的问题。请注意,我可以通过在Visual Studio生成的警告中搜索来找到这些内容。
  2. 实体中的属性类型BitmapImage的部分类 - 将属性的类型更改为BitmapSource(BitmapImage的直接继承父级)是此处的修复。

答案 2 :(得分:-1)

我收到此错误是因为我在多个元素的结果上调用了.Single()

工具提示中的方法说明说明:

  

返回序列的唯一元素,如果出现异常则抛出异常   序列中没有一个元素。

(如果您尝试查找多个元素中的第一个元素,则可能正在寻找.First()而不是.Single()。)