0

您好,我正在尝试使用微风 1.3.4 执行查询。我的查询如下

function getContacts() {

            var query = breeze.EntityQuery
                .from("Contacts").where("Desc", "startsWith", "P");


            return manager.executeQuery(query)
              .then(getSucceeded).fail(getFailed); 

        }

“Desc”是我的“Contacts”C# 后端模型中的字符串属性。问题是查询 URL 的格式如下.../api/Application/Contacts?$filter=startswith(Desc%2Ctime'P')%20eq%20true

在“P”之前添加了时间这个词,我在响应中得到了这个异常

{"$id":"1","$type":"System.Web.Http.HttpError, System.Web.Http","Message":"The query specified in the URI is not valid.","ExceptionMessage":"Unrecognized 'Edm.Time' literal 'time'P''

如果在比较中我使用小写“p”,那么 Url 将被构建,因为它应该是这样的 "$filter=startswith(Desc%2C'p')%20eq%20true` 。

使用英文字母的其他大写字母时,我没有同样的问题。

有谁知道我错过了什么,我无法弄清楚为什么在该特定查询中添加了“时间”一词?

谢谢你。

4

1 回答 1

0

我们能够重现该问题。

虽然异常消息令人困惑,但我相信您可能会收到错误消息,因为您没有将资源名称“Contacts”与可能为“Contact” 的EntityType关联起来。

发生的情况是,当 Breeze 尝试构建查询时,它通常会使用其元数据来正确格式化 url 查询字符串以发送到服务器。此过程的关键部分涉及确定与查询的“from”子句中给出的resourceName关联的EntityType (在您的情况下为“Contacts”)。Breeze 使用资源名称到实体类型映射来执行此操作,但如果它找不到映射,它仍然会继续构建 url,因为我们仍然需要支持针对我们没有元数据的端点的临时请求。

您可以通过MetadataStore.setEntityTypeForResourceName方法自行更新此地图。如果您使用的是实体框架,则此映射最初是根据作为 EDMX 模型一部分的实体类型名称/实体集名称映射填充的。因此,在您的情况下,您可以修改 EDMX 模型或直接调用 setEntityTypeForResourceName 方法。

不幸的是,如果没有元数据,Breeze 必须推断查询中的数据类型。所以在你的情况下

"Desc", "startsWith", "P"

由于 Breeze 无法确定“Desc”是您的 Contract EntityType 的“字符串”属性,它会尝试根据值“P”推断“Desc”的“dataType”。不幸的是,'P' 是一个有效的 ISO8601 'duration' 值(一种表达 'Time' 数据类型的方法),因此 Breeze 错误地尝试构造一个将 'P' 视为 'Time' 常量的查询字符串。这就是您的代码使用小写“p”(不是有效的持续时间值)的原因。

这种推理逻辑当然可以改进,我们有一个修复程序,可以让我们在下一个版本中完全做到这一点。但是...解决此类问题的更好和更通用的解决方案是首先正确地获取“resourceName/entityType”映射。

希望这可以帮助。

于 2013-05-31T00:15:36.450 回答