【问题标题】:Possible bug in breeze 1.4.14微风 1.4.14 中可能存在的错误
【发布时间】:2014-08-01 03:21:43
【问题描述】:

我没有针对几周前发布的 1.4.16 版本对此进行测试,但发行说明中没有任何相关内容。

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

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”与属性名称进行比较,而是将属性名称与自身进行比较。

我没有测试过每个运算符,但据我所知,无论你使用哪个运算符,你都会得到相同的行为。

您在查询导航属性时也会遇到同样的问题,但通常会导致查询无效。下面是同一实体的谓词,但针对包含 ItemTag 实体集合的导航属性标签,这些实体具有“标签”属性。

breeze.Predicate.create('tags', breeze.filterQueryOp.Any, 'tag', breeze.filterQueryOp.Contains, 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) 

由于 ItemTag 实体上存在属性 Tag,因此会产生“无法在类型 'Item' 上找到名为 'Tag' 的属性”的错误。

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

有没有其他人遇到过这种情况?

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

我不确定它是否相关,因为服务器似乎正确响应了请求,并且创建不正确的请求很容易,但在服务器端我使用 Web API oData 控制器和 EF 作为 ORM 数据层。

【问题讨论】:

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


    【解决方案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

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

    这种逻辑的原因是允许表达式两边都是属性。例如,要查询具有相同名字和姓氏的员工,您可以这样做:

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

    如果您想要姓氏为“firstName”的员工,您可以这样做:

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

    【讨论】:

    • 感谢它的工作原理,尽管由于某种原因,当我查询一个值为“tag”的项目时,当标签集合中只有一个具有该标签但如果我查询“tag1”,然后它正确返回带有此标签的 2 条记录。我不认为这是微风的问题,因为除了传递的值之外,oData 请求在两种情况下都是相同的,如果我使用浏览器发出请求并手动更改值,我会得到相同的结果。跨度>
    猜你喜欢
    • 1970-01-01
    • 2013-08-04
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 2013-10-11
    • 2019-12-22
    • 2012-01-21
    相关资源
    最近更新 更多