使用OData Wep Api在数据传输对象上嵌套filter

我有一个wep api项目使用odata消耗数据但是我遇到了odata wep api的一些问题。

当我执行该查询时

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

它给了我以下错误

“消息”:“URI中指定的查询无效。”,“ExceptionMessage”:“属性’Fortuneteller’的属性访问的父值不是单个值。属性访问只能应用于单个值。”

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

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

api controller service repository EF

api控制器

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

服务

  public IQueryable FiterBy(Expression<Func> 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 List() { return context.CreateObjectSet(); } 

DTO的

 public class FortuneDTO { public int Id { get; set; } public string CreatedByFullName { get; set; } public IQueryable 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; } } 

正如exception消息所示,您拥有的查询无效。

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