1

我正在尝试使用 DateTimeOffset 列上的谓词查询我的实体,但从 Breeze.WebApi 获得 500 错误响应。错误信息是

Unable to perform operation: leon types:System.Nullable`1[System.DateTimeOffset], System.DateTime

我看到产生的uri类似于

http://localhost:49800/api/Breeze Orders?$filter=LocalDateTime%20le%20datetime'2013-03-03T00%3A00%3A00.000Z'

什么工作:

  • 我可以查询其他日期时间、文本列
  • 我可以将新数据保存到我的“LocalDateTime”字段中

查询的完整错误响应是:

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Unable to perform operation: leon types:System.Nullable`1[System.DateTimeOffset], System.DateTime
</ExceptionMessage>
<ExceptionType>System.Exception</ExceptionType>
<StackTrace>
at Breeze.WebApi.ParseTreeVisitor.CoerceTypes(String operatorName, Expression& leftExpr, Expression& rightExpr) at Breeze.WebApi.ParseTreeVisitor.VisitBinary(ParseTreeNode node, String operatorName, Expression leftExpr, Expression rightExpr) at Breeze.WebApi.ParseTreeVisitor.VisitNode(ParseTreeNode node) at Breeze.WebApi.ParseTreeVisitor.Parse(Type rootType, ParseTreeNode node) at Breeze.WebApi.ExpressionTreeBuilder.Parse(Type rootType, String source) at Breeze.WebApi.ODataActionFilter.BuildFilterFunc(String filterQueryString, Type elementType) at Breeze.WebApi.ODataActionFilter.OnActionExecuted(HttpActionExecutedContext actionExecutedContext) at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception) at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response) at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t) at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)
</StackTrace>
</Error>

.

编辑

到达那里,但不完全。安装 Breeze 1.2.8 后,客户端现在生成正确类型的 uri,例如

http://localhost:49800/api/Breeze/Orders?$filter=LocalDateTime%20ge%20datetimeoffset'2013-01-01T11%3A00%3A00.000Z'

在我的情况下,不需要使用 setEntityTypeForResourceName 来修复实体类型。上面的uri仍然给我错误:

Unable to perform operation: leon types:System.Nullable`1[System.DateTimeOffset], System.DateTimeOffset

从更改我的服务器端模型

public Nullable<System.DateTimeOffset> LocalDateTime { get; set; }

public System.DateTimeOffset LocalDateTime { get; set; }

允许我的 uri 工作。那么我们能否修复可为空的 DateTimeOffset。

4

1 回答 1

1

这在 v 1.2.7 中已修复。如果您仍然看到错误,请回帖。

- - 更多信息 - -

自 1.2.7 以来已经有几个帖子表明此错误仍在发生。事实证明,问题不在于微风不理解“dataTimeOffsets”。除了涉及“DateTimeOffsets”的查询之外,微风非常宽容查询中不正确的实体类型/资源名称映射。这篇文章有点长,所以如果您只需要修复,请阅读最后一段。

当查询中声明的资源名称('from' 子句中的值)无法映射到现有 entityType 名称(定义在元数据)。

如果微风可以找到映射到查询中声明的资源名称的实体类型,它将使用该实体类型的元数据来验证查询并创建 OData 过滤器字符串。但是,如果它找不到匹配的实体类型,这是一个完全可以接受的条件,因为某些“资源名称”不会映射到实体,它会尝试通过查看查询中涉及的任何常量参数来推断任何查询子句中涉及的数据类型并使用他们的数据类型。问题是 javascript 日期对象可以映射到 .NET 的“DateTime”或“DateTimeOffset”,而 Breeze 只能选择一个,在这种情况下会选择“错误”的那个。

当从查询返回数据时,这种错误映射不会导致问题,因为微风仅使用查询的实体类型来验证和构造适当的 OData 过滤器字符串。检查从任何查询返回的数据以确定返回的每个项目的实体类型,因此不需要资源名称/实体类型映射。(由于使用了“expand”或“select”子句,单个查询可能会返回多个实体类型。)

映射问题的根本原因涉及到资源名称到实体类型的映射,这些实体类型在每个 MetadataStore 中保持不变。此映射可通过MetadataStore.getEntityTypeNameForResourceNameMetadataStore.setEntityTypeForResourceName方法获得。使用实体框架元数据时,微风假定实体框架“EntitySet”名称对应于“resourceNames”。 这个假设是造成问题的原因。如果您查询与您的 EntitySet 名称之一不同的“resourceName”,Breeze 不知道相应的“实体类型”,并回退到推断查询中使用的数据类型,而不是使用“实体类型”元数据。

有两个相当简单的修复,其中任何一个都有效。

1) 使用 MetadataStore.setEntityTypeForResourceName 方法将您的资源名称映射到您的实体类型。请注意,您可以将任意数量的资源名称映射到相同的实体类型。

2) 将您的方法(对应于资源名称)命名为 EF 中定义的相应 EntitySet 的名称,而不是返回的类型的名称。一个常见的约定是 EntitySet 名称(以及资源​​名称)是复数形式,而 EntityType 名称通常是单数形式。即“客户”是资源名称,“客户”是实体类型

于 2013-03-19T04:52:12.130 回答