我有一个非标准的BreezeController查询,它返回一个“假”IQueryable作为资源,使用标准的breeze EntityQuery js类从客户端进行查询。这个伪查询构建了一个由Entity Framework映射的Entity对象的集合,因此被内存中的breeze 知道并将它们作为IQueryable返回。
我已经将问题与编写投影查询隔离开来,该投影查询选择在服务器上的内存中填充的属性作为同一实体类型的其他实例的子集合。
此查询在breeze 1.4.2中有效。升级到1.4.6(和相关库)后,此查询现在向客户端返回错误响应:“URI中指定的查询无效”。
我已经逐步完成了BreezeController中的服务器端查询方法,并且看到正在构造对象的内存中列表而没有抛出异常。一旦控制权传回breeze,其余的响应管道就会发生,导致客户端出现错误响应。
为了进一步研究这个问题,我需要逐步完成更多的响应管道,但不确定如何最好地实现这一点。
我已尝试启用Visual Studio选项“启用.NET框架源步进”,但这似乎无法找到/下载足够数量的调试符号以进入像Breeze,JSON这样的事情, Web API,OData等
一旦抛出CLR异常,我就尝试将Visual Studio配置为中断。但是服务器端似乎没有例外。
我想知道Breeze的某个人是否可以提供一些建议吗? 也许微风中有一些额外的代码挂钩我可以编写一些我自己的代码来简单插入以便我可以设置一些断点并进一步隔离有问题的管道中的阶段。
由于 基督教
答案 0 :(得分:3)
直到breeze发布每个dll的.pdb文件为止,你需要从Github下载源代码,编译并手动将pdb文件复制到breeze NuGet包中:
将pdb文件复制到NuGet包中是 I 在想要单步执行时能够让Visual Studio识别并加载pdb文件的唯一方法。我尝试通过右键单击调用堆栈框来加载符号,但当我指向breeze源代码bin目录中的pdb文件时,VS抱怨了。
在BreezeQueryableAttribute
和关联的帮助程序类QueryHelper
中找到了要调试的有趣代码的主体。我发现进入此代码的最简单方法是创建BreezeQueryableAttribute
的子类,并在此子类中覆盖OnActionExecuted
方法。装饰IQueryable方法
在BreezeController中使用这个新属性。
使用新的子类属性,您可以在子类中的OnActionExecuted
上设置断点,然后从那里步进BreezeQueryableAttribute.OnActionExecuted
。
为方便起见,这里是我创建的子类属性:
using Breeze.WebApi2;
public class DebugBreezeQueryable : BreezeQueryableAttribute
{
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
}
}
正如我所怀疑的那样:QueryableAttribute.ValidateQuery
抱怨尝试$选择一个EF / breeze未映射的属性(在本例中是一个名为Children的属性)。有趣的是,这在微风的1.4.2中运行良好。
我提出的解决方法是改为创建一个未映射到数据库的DTO类,并从数据库加载的Entity对象中填充这些DTO在内存中的实例;将这些DTO作为IQueryable返回。我认为关键是这些DTO类没有映射到EF / breeze中。
为了完整性,这里是失败的查询中涉及的有趣代码的摘录:
客户端查询:
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 */
}
答案 1 :(得分:0)
您是否可以发布相关的服务器端端点代码以及它尝试执行的客户端查询。
根据您的第二个问题,Breeze源代码可在GitHub上获得,您可以通过更改refs直接下载并调试到Breeze EF库,直接指向源代码的下载版本。