使用 OData Wep API 的数据传输对象上的嵌套筛选器

本文关键字:嵌套 筛选 对象 数据传输 OData Wep API 使用 | 更新日期: 2023-09-27 18:32:11

我有一个 wep api 项目使用 odata 使用数据,但我在使用 odata wep api 时遇到了一些问题。

当我执行该查询时

/

api/values?$top=50&$filter=Comments/Fortuneteller/FullName eq 'some string'

它给了我以下错误

"消息": "URI 中指定的查询无效。 "异常消息":"属性'算命先生'的属性访问的父值不是单个值。属性访问只能应用于单个值。

我不想从控制器返回实体对象。有没有办法通过DTO过滤实体?

我在我的项目中使用存储库 + 服务层模式,我的项目结构是这样的

API 控制器 <->

服务 <-> 存储库<-> EF

接口控制器

    [Queryable]
    public IQueryable<FortuneDTO> Get()
    {
        return service.FiterBy((_ => true));
    }

服务

    public IQueryable<FortuneDTO> FiterBy(Expression<Func<tblFortune, bool>> filter)
    {
        return repository.List().Where(filter).Select(_ => new FortuneDTO
        {
            CreatedByFullName = _.aspnet_Users.FullName,
            Id = _.FortuneId,
            Comments = _.tblComment.Select(c => new CommentDTO
            {
                Id=c.CommentId,
                Comment = c.Comment,
                Fortuneteller = new FortunetellerDTO { 
                    FullName=c.aspnet_Users.FullName,
                    Id=c.aspnet_Users.UserId
                }
            }).AsQueryable()
        });
    }

存储 库

    public virtual IQueryable<TEntity> List()
    {
        return context.CreateObjectSet<TEntity>();
    }

DTO的

public class FortuneDTO
{
    public int Id { get; set; }
    public string CreatedByFullName { get; set; }
    public IQueryable<CommentDTO> Comments { get; set; }
}
public class CommentDTO
{
    public int Id { get; set; }
    public string Comment { get; set; }
    public FortunetellerDTO Fortuneteller { get; set; }
}
public class FortunetellerDTO
{
    public Guid Id { get; set; }
    public string FullName { get; set; }
}

使用 OData Wep API 的数据传输对象上的嵌套筛选器

正如异常消息告诉您的那样,您拥有的查询无效。

/api/values?$top=50&$filter=Comments/Fortuneteller/FullName eq 'some string'

等效于 linq 表达式

fortuneDTOs.Where(f => f.Comments.Fortuneteller.FullName == "some string").Top(50)

如您所见fortuneDTOs.Comments.Fortuneteller不正确,因为注释是一个集合,它没有名为"FullName"的属性。

应使用"任何/全部"筛选集合。例如,如果您试图找到其中一个评论员是"一些字符串"的所有财富,您可以这样做

/api/values?$top=50&$filter=Comments/any(c: c/Fortuneteller/FullName eq 'some string')
相反,如果您想找出所有评论仅

由一个评论员"某个字符串"发表的所有财富,您可以这样做

/api/values?$top=50&$filter=Comments/all(c: c/Fortuneteller/FullName eq 'some string')