我想使用一些外部服务器端逻辑来修改查询结果的属性。为此,我需要应用Breeze查询选项,修改结果集并返回它。
我基本上知道如何将OdataQueryOptions
应用于我的查询,但我不想错过BreezeJS所做的所有Web Api的OData所没有做的事情。例如,我想保留inlineCount
。
我该怎么做?有没有办法挂钩Breeze的查询修改代码?
如果重要,我正在使用Entity Framework 6和Web Api 2。
答案 0 :(得分:3)
好的,我不确定是否有更好的方法(因为这看起来像是一个常见的用例似乎很多工作),但这里有我怎么做解决了这个问题。
我从QueryHelper
类继承来修改PostExecuteQuery
方法来执行委托。
public class ExtendedQueryHelper : QueryHelper
{
public ExtendedQueryHelperOptions Options { get; set; }
public ExtendedQueryHelper(ODataQuerySettings querySettings) : base(querySettings)
{}
public override IEnumerable PostExecuteQuery(IEnumerable queryResult)
{
if (Options != null && Options.PostExecuteQueryHandler != null)
{
return Options.PostExecuteQueryHandler(queryResult);
}
return base.PostExecuteQuery(queryResult);
}
}
委托在名为ExtendedQueryHelperOptions
public class ExtendedQueryHelperOptions
{
private const string EXTENDED_QUERY_HELPER_OPTIONS_KEY = "EXTENDED_QUERY_HELPER_OPTIONS_KEY";
public delegate IEnumerable PostExecuteQueryDelegate(IEnumerable queryResult);
public PostExecuteQueryDelegate PostExecuteQueryHandler { get; set; }
public void InjectIntoRequest(HttpRequestMessage request)
{
request.Properties.Add(EXTENDED_QUERY_HELPER_OPTIONS_KEY, this);
}
public static ExtendedQueryHelperOptions GetFromRequest(HttpRequestMessage request)
{
object options;
request.Properties.TryGetValue(EXTENDED_QUERY_HELPER_OPTIONS_KEY, out options);
return (ExtendedQueryHelperOptions)options;
}
}
为了设置这些选项,我必须继承BreezeQueryableAttribute
并在创建QueryHelper
时注入这些选项:
public class ExtendedBreezeQueryableAttribute : BreezeQueryableAttribute
{
protected HttpRequestMessage Request { get; set; }
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
Request = actionContext.Request;
base.OnActionExecuting(actionContext);
}
protected override QueryHelper NewQueryHelper()
{
var queryHelper = new ExtendedQueryHelper(GetODataQuerySettings());
queryHelper.Options = ExtendedQueryHelperOptions.GetFromRequest(Request);
return queryHelper;
}
}
现在我可以注入要在过滤结果上运行的代码,如下所示:
[BreezeController]
public class BreezeController : BaseController
{
//...
[HttpGet]
[ExtendedBreezeQueryable]
public IQueryable<Foo> Foos()
{
var options = new ExtendedQueryHelperOptions
{
PostExecuteQueryHandler = delegate(IEnumerable results) {
// This code will be run after the querying has been
// applied by Breeze
var foos = results.Cast<Foo>().ToList();
foreach (var foo in foos)
{
foo.ComputedProperty = ComputeSomething();
}
return foos;
}
};
// Inject these options into the Request, so the ExtendedBreezeQueryableAttribute
// can get to them later
options.InjectIntoRequest(Request);
return Db.Foos;
}
}
答案 1 :(得分:0)
我在这里看了答案并且努力与之相抗衡,所以想出了一些更简单的东西(但可能远远不如此)。
假设您要修改Breeze查询返回的实体,然后在查询末尾添加.ToList()
,修改列表项,并使用'list.AsQueryable()'返回它们,如下所示:< / p>
public IQueryable<CameraMetaData> CameraMetaDatas()
{
var query = ContextProvider.Context.Cameras;
var list = query.ToList();
foreach(var l in list)
{
//modify values
}
return list.AsQueryable();
}