使用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')