如何在Web Api中手动执行Breeze过滤器?

时间:2014-05-21 21:43:06

标签: .net entity-framework asp.net-web-api odata breeze

我想使用一些外部服务器端逻辑来修改查询结果的属性。为此,我需要应用Breeze查询选项,修改结果集并返回它。

我基本上知道如何将OdataQueryOptions应用于我的查询,但我不想错过BreezeJS所做的所有Web Api的OData所没有做的事情。例如,我想保留inlineCount

我该怎么做?有没有办法挂钩Breeze的查询修改代码?

如果重要,我正在使用Entity Framework 6和Web Api 2。

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();
}