使用DateTimeOffset列上的谓词查询Breeze时出错

时间:2013-03-07 22:10:05

标签: breeze

我正在尝试使用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'

工作原理:

  • 我可以查询其他DateTime,文本列
  • 我可以将新数据保存到我的'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进行修复。

1 个答案:

答案 0 :(得分:1)

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

---更多信息---

自1.2.7以来,有几个帖子表明此错误仍然存​​在。事实证明,问题不在于微风不理解'dataTimeOffsets'。对于涉及'DateTimeOffsets'的查询,查询之外的不正确的 EntityType /资源名称映射是微不足道的。这篇文章有点长,所以如果你只需要修复,请阅读最后一段。

当查询中声明的资源名称('from'子句中的值)不能执行对dateTimeOffset属性的查询时,会出现“无法执行操作:...”错误被映射到现有的entityType名称(在元数据中定义)。

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

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

映射问题的根本原因涉及资源名称到breeze在每个MetadataStore中保留的实体类型的映射。此映射可通过 MetadataStore.getEntityTypeNameForResourceName MetadataStore.setEntityTypeForResourceName 方法获得。使用Entity框架元数据时,breeze假定Entity Framework的“EntitySet”名称对应于“resourceNames”。 这个假设是造成问题的原因。如果查询的“resourceName”与您的某个EntitySet名称不同,则Breeze不知道相应的“实体类型”,而是依赖于推断查询中使用的数据类型,而不是使用“实体类型”元数据。 / p>

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

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

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