您好我正在尝试使用breezejs 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`。
使用英文字母的其他UpperCase字母时,我没有遇到同样的问题。
有没有人知道我错过了什么,我无法弄清楚为什么在该特定查询中添加“时间”这个词?
谢谢。
答案 0 :(得分:0)
我们能够重现这个问题。
虽然异常消息令人困惑,但我相信您可能会收到错误,因为您没有将资源名称“Contacts”与 EntityType 相关联,大概是“Contact”。
发生的事情是,当Breeze尝试构建查询时,它通常会使用其元数据来正确格式化要发送到服务器的url查询字符串。此过程的关键部分涉及确定与查询的“from”子句中给出的 resourceName 关联的 EntityType (在您的案例中为“Contacts”)。 Breeze使用资源名称实体类型映射来执行此操作,但如果它找不到映射,它仍将继续构建URL,因为我们仍需要支持针对我们没有元数据的端点的临时请求。
您可以通过MetadataStore.setEntityTypeForResourceName方法自行更新此地图。如果您使用的是Entity Framework,则最初会根据作为EDMX模型一部分的EntityType名称/实体集名称映射来填充此映射。因此,在您的情况下,您可以修改EDMX模型或直接调用setEntityTypeForResourceName方法。
不幸的是,如果没有元数据,Breeze必须推断出查询中的数据类型。所以在你的情况下
"Desc", "startsWith", "P"
由于Breeze无法确定“Desc”是您的Contract EntityType的“字符串”属性,它会尝试根据值“P”推断出“Desc”的“dataType”。不幸的是,'P'是一个有效的ISO8601'持续时间'值(一种表达'Time'数据类型的方式),因此Breeze错误地尝试构造一个查询字符串,其中'P'被视为'Time'常量。这就是为什么你的代码使用小写'p'(不是有效的持续时间值)。
这种推理逻辑肯定可以改进,而且我们有一个修复程序,可以让我们在下一个版本中完成。然而......对这类问题更好,更通用的解决方案是首先使'resourceName / entityType'映射正确。
希望这有帮助。