c# - 使用 OData Web Api 对数据传输对象进行嵌套筛选

标签 c# asp.net-mvc-4 asp.net-web-api odata

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

当我执行那个查询时

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

它给了我以下错误

"Message": "The query specified in the URI is not valid.", "ExceptionMessage": "The parent value for a property access of a property 'Fortuneteller' is not a single value. Property access can only be applied to a single value."

我不想从 Controller 返回实体对象。有什么方法可以通过 DTO 过滤实体吗?

我在我的项目中使用 Repository + Service 层模式,我的项目结构就是这样

api controller <-> service <-> repository <-> EF

API Controller

    [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; }
}

最佳答案

异常消息告诉您,您的查询无效。

/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 是不正确的,因为 Comments 是一个集合并且它没有名为“FullName”的属性。

您应该使用 Any/All 来过滤集合。例如,如果您试图找到其中一位评论员是“某个字符串”的所有命运,您可以这样做

/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')

关于c# - 使用 OData Web Api 对数据传输对象进行嵌套筛选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18912222/

相关文章:

c# - 如何在 Web Api 中使用 Api key 使用表单例份验证进行服务身份验证

C# .Net6.0-如何通过C#更改Windows页面文件大小(虚拟内存)?

c# - 为什么选择 System.Threading 而不是 BackgroundWorker?

c# - 截取未打开的文件夹窗口的屏幕截图

asp.net-mvc - 获取 .cshtml 模板中的 MaxLength 值

c# - 如何编写 Nhibernate 查询

C# 属性检查一个日期是否早于另一个日期

c# - 如何以编程方式调用css的 "click"

c# - Web API 2 不工作 (404)

python - 使用自定义装饰器/属性记录 Python Bottle API