在服务器端调试 breeze 查询的最直接方法是什么?



我有一个非标准的BreezeController查询,它返回一个"假的"IQueryable作为资源,以使用标准的breeze EntityQuery js类从客户端进行查询。这个假查询在内存中建立了一个由Entity Framework映射的Entity对象集合,因此被breez所知,并将这些对象作为IQueryable返回。

我已经将这个问题隔离为与编写一个投影查询有关的问题,该查询选择了一个在服务器内存中填充的属性作为同一实体类型的其他实例的子集合。

此查询在微风1.4.2时起作用。在升级到1.4.6(以及相关库)之后,此查询现在向客户端返回一个错误响应:"URI中指定的查询无效"。

我已经逐步完成了BreezeController中的服务器端查询方法,并看到正在构建内存中的对象列表,而没有抛出异常。一旦控制权返回到微风和响应管道的其余部分,就会发生一些事情,导致错误响应返回到客户端。

为了进一步调查这个问题,我需要通过更多的响应管道,但不确定如何最好地实现这一点。

我试着打开Visual Studio选项"启用.NET框架源代码步进",但这似乎无法找到/下载足够数量的调试符号,无法进入Breeze、JSON、Web API、OData等

我已尝试将Visual Studio配置为在引发CLR异常时立即中断。但服务器端似乎没有出现异常。

我想知道Breeze是否有人能提供一些建议 也许breeze中还有一些额外的代码挂钩,我可以编写一些自己的代码来插入,这样我就可以设置一些断点,并进一步隔离管道中出现问题的阶段

谢谢Christian

A:如何在服务器上调试微风查询

在breeze发布每个dll的.pdb文件之前,您需要从Github下载源代码,编译并手动将pdb文件复制到breeze NuGet包中:

  1. 下载breeze源代码
    • 浏览到https://github.com/IdeaBlade/Breeze
    • 下载与您需要调试的微风版本相匹配的源代码版本(提示:您需要使用"分支"按钮来选择特定标记)
  2. 编译breeze源代码:
    • 打开VS解决方案文件-Breeze.Build.sln
    • 打开Visual Studio后,使用Configuration Manager对话框更改为Release build(这假设您要调试一组发布版本dll的,即Breeze.js在其NuGet中发布的dll)
    • 重建解决方案-这将在breeze NuGet包中构建dll的精确副本,及其关联的.pdb文件
  3. 将pdb文件复制到相应的NuGet-lib目录中:
    • 例如:\bin\Release \Breeze.ContextProvider.pdb->packages\Breeze.Server.ContextProvider.n.n\lib

将pdb文件复制到NuGet包中是I让Visual Studio在想要逐步完成时识别并加载pdb文件的唯一方法。我试图通过右键单击调用堆栈帧来加载符号,但当我指向breeze源代码bin目录中的pdb文件时,VS抱怨道。

逐步通过微风服务器端查询

看起来,要调试的感兴趣的代码的主体位于BreezeQueryableAttribute和相关的辅助类QueryHelper中。我发现进入此代码的最简单方法是创建BreezeQueryableAttribute的子类,并在该子类中重写OnActionExecuted方法。装饰IQueryable方法在BreezeController中使用此新属性。

有了新的subclasses属性,您可以在子类中的OnActionExecuted上设置断点,然后从那里进入BreezeQueryableAttribute.OnActionExecuted

为了方便起见,下面是我创建的子类属性:

using Breeze.WebApi2;
public class DebugBreezeQueryable : BreezeQueryableAttribute
{
    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
    }
}

A: 为什么升级后对"假"IQueryable的投影查询失败

正如我所怀疑的那样:QueryableAttribute.ValidateQuery抱怨试图$选择一个EF/微风未映射的属性(在本例中是一个名为Children的属性)。有趣的是,这在微风的1.4.2版本中运行良好。

我想出的解决方法是创建一个没有映射到数据库的DTO类,并从数据库加载的Entity对象中填充内存中这些DTO的实例;以IQueryable的形式返回这些DTO。我认为关键是这些DTO类没有映射到EF/微风中。

为了完整起见,这里摘录了失败查询中涉及的有趣代码:

客户端查询:

query = breeze.EntityQuery
            .from("ScreenEntityUIs")
            .where("id", "==", parseInt(id, 10))
            .select("Id, EntityId, Children, AdditionalData, IsModal, IsList");

服务器端查询:

    public IQueryable<EntityUI> ScreenEntityUIs()
    {
        var sql = BuildEntityUIsQuery();
        var all = this.contextProvider.Context.Database.SqlQuery<EntityUI>(sql).ToList();
        var results = new List<EntityUI>();
        var roots = all.Where(p => p.ParentId == null);
        foreach (var root in roots)
        {
            this.BuildChildrenList(root.Id, all, root);
            results.Add(item);
        }
        return results.AsQueryable();
    }

实体类:

public class EntityUI : StateInfo
{
    public EntityUI()
    {
        this.Children = new Collection<EntityUI>();
    }
    public int Id { get; set; }
    public int? ParentId { get; set; }
    [NotMapped]
    public virtual ICollection<EntityUI> Children { get; set; }
    /* snip */
}

您可以发布相关的服务器端端点代码和它试图执行的客户端查询吗。

根据您的第二个问题,Breeze源代码在GitHub上可用,您可以通过将refs更改为直接指向源代码的下载版本,直接下载并调试到Breeze EF库中。

相关内容

最新更新