我有一个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< - >服务< - >存储库< - > EF
api控制器
[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; }
}
答案 0 :(得分:28)
正如异常消息所示,您拥有的查询无效。
/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')