微风1.4.14中可能存在的错误

时间:2014-07-31 12:18:44

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

我没有对几周前发布的1.4.16版本进行测试,但发布说明中没有任何内容可以解决。

问题出现在谓词中,您要比较的值与Breeze知道的任何实体上的属性名称相同。一个简单的测试用例是:

var query = breeze.EntityQuery.from('Items');

var pred = breeze.Predicate.create('name', breeze.FilterQueryOp.Contains, searchTerm);

query = query.where(pred);

其中searchTerm等于" name"以外的任何字符串。这会产生一个oData查询,如下所示:

Items?$filter=(substringof(%27somevalue%27%2CName)%20eq%20true)

但是如果searchTerm =" name"然后它产生以下查询

Items?$filter=(substringof(Name%2CName)%20eq%20true)

这不是比较字符串'名称'对于属性Name,它将属性Name与其自身进行比较。

我没有对每个操作员进行过测试,但据我所知,无论你使用哪种操作都没关系。

查询导航属性时也会遇到同样的问题,但通常会导致查询无效。下面是同一个实体的谓词,但是针对导航属性标签,该标签包含一个具有"标签"对他们的财产。

breeze.Predicate.create('tags', breeze.filterQueryOp.Any, 'tag', breeze.filterQueryOp.Contains, searchTerm)

它适用于除"标记"以外的任何searchTerm。它产生一个oData请求,如下所示:

Items?$filter=Tags%2Fany(x1%3A%20substringof(%27somevalue%27%2Cx1%2FTag)%20eq%20true)

但是如果searchTerm是"标记"然后它要求:

Items?$filter=Tags%2Fany(x1%3A%20substringof(Tag%2Cx1%2FTag)%20eq%20true) 

产生错误"找不到名为' Tag'在类型'项目'"因为ItemTag实体上存在属性Tag。

简而言之,似乎推断任何与其所知的属性名称相同的搜索词都指的是该属性,而不是字符串文字值。

还有其他人遇到过这个吗?

这是一个错误,还是有办法明确告诉breeze将该值解释为字符串文字而不是对属性的引用?

我不确定它是否相关,因为服务器似乎正在对请求做出正确响应,而且很容易创建不正确的请求,但在服务器端我使用的是带有EF作为ORM数据层的Web API oData控制器。 / p>

1 个答案:

答案 0 :(得分:1)

尝试

var pred = breeze.Predicate.create('name', breeze.FilterQueryOp.Contains, 
 { value: searchTerm, isLiteral: true} );

这里描述(在value参数的解释下): http://www.breezejs.com/sites/all/apidocs/classes/Predicate.html#method_create

  

如果值可以解释为属性表达式,则将其视为文字。        在大多数情况下,这种方法效果很好,但您也可以通过使值参数本身成为具有“'值”的对象来强制进行解释。财产和' isLiteral'属性设置为true或false。        Breeze还尝试根据上下文推断任何文字的dataType,如果失败,你可以通过使value参数成为具有'值的对象来强制进行推理。属性和“数据类型”属性集         到其中一个breeze.DataType枚举实例。

这种逻辑的原因是允许表达式两边都是属性的表达式。例如,要查询具有相同名字和姓氏的员工,请执行以下操作:

var q = EntityQuery.from("Employees")
        .where("lastName", "==", "firstName");

而如果您希望员工的姓氏为' firstName'你这样做:

var q = EntityQuery.from("Employees")
        .where("lastName", "startsWith", { value: "firstName", isLiteral: true })