如果我有以下自定义模型/ DTO,请使用Microsoft WebAPI OData 5.6版(OData v3):
public class ParentObject
{
public int ID { get; set; }
public string Title {get; set;}
public ChildObject Child { get; set;}
}
public class ChildObject
{
public string Value { get; set;}
}
以下控制器将我的数据库投射到模型中:
public class ParentsController : ODataController
{
public IQueryable<ParentObject> Get()
{
var db = new MyDBContext();
var results = from p in db.parent
select new ParentObject
{
ID = p.id,
Title = p.title,
Child = p.child == null ? null : new ChildObject
{
Value = p.child.value
}
};
return results;
}
}
}
如果消费者不需要在网址中指定$ expand = Child,我如何强制扩展“Child”?
我想:
1.检查消费者是否已指定$ expand = Child
2.如果展开列表中尚未包含“儿童”,请将其包括在内
3.请务必遵守任何其他查询选项
我查看了一些在线文章,这些文章要么我不清楚,要么引用不再匹配的旧版api。
我尝试将Action修改为“Get(ODataQueryOptions opts)”,这让我做了类似的事情:
if(opts.SelectExpand == null || !opts.SelectExpand.RawExpand.Contains("Child"))
{
// Add/modify expand clause here.
}
但是我不清楚如何修改或构建我自己的ODataQueryOptions对象,维护所有其他查询选项,然后将其应用于结果。
更新1
我取得了一些进展。这是对控制器的相关更改(dbcontext查询与上面相同):
public PageResult<ParentObject> Get(ODataQueryOptions opts)
{
SelectExpandQueryOption expandOpts = null;
if(opts.SelectExpand != null && !opts.SelectExpand.RawExpand.Contains("Child"))
{
expandOpts = new SelectExpandQueryOption(opts.SelectExpand.RawSelect, string.Join(",", new string[] {"Child", opts.SelectExpand.RawExpand }), opts.Context);
}
else if (opts.SelectExpand == null)
{
expandOpts = new SelectExpandQueryOption(null, "Child", opts.Context);
}
// Query from above goes here
if(expandOpts != null)
{
Request.SetSelectExpandClause(expandOpts.SelectExpandClause);
}
var qSettings = new ODataQuerySettings();
qSettings.PageSize = 100;
results = opts.ApplyTo(results, qSettings).AsQueryable() as IQueryable<ParentObject>;
return new PageResult<ParentObject>(results, Request.GetNextPageLink(), Request.GetInlineCount());
}
当我不包含“$ expand”查询选项(创建expandOpts)时,这似乎工作正常。但是,当“$ expand”存在时,我在return语句中得到一个ArgumentNullExcpetion,并且无法找出原因。
答案 0 :(得分:1)
仔细看看底部:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options。 MyQueryableAttribute可能就是您所需要的。您可以创建一个自定义QueryableWithChildAttribute
类,它会注入您需要的queryOptions.Expand。然后,只需使用[QueryableWithChild()]
装饰您的方法。
希望这有帮助。
答案 1 :(得分:1)
在这个问题上花了好几个小时后,这才是答案。您需要设置扩展字符串并执行包含以使其正常工作。
[EnableQuery]
public IQueryable<Student> Get_Student(ODataQueryOptions<Student> queryOptions)
{
var db = new EfCustomAdapter();
var expandOpts = new SelectExpandQueryOption(null, "Parent,Schools", queryOptions.Context);
var q = db.Student.AsQueryable();
q = q.Include(t => t.Parent);
q = q.Include(t => t.Schools);
queryOptions.Request.ODataProperties().SelectExpandClause = expandOpts.SelectExpandClause;
return q;
}
更新: 如果你需要扩展低于语法的级别.. “父母,学校,票据/付款”
付款对象是账单的导航属性。