你快到了!:-) 如果您EntityType
在查询中指定了目标,我认为它会起作用。
尝试这个:
var query = EntityQuery.from(resource).orderBy(ordering)。toType('Esto') ;
该toType()
方法告诉 Breeze 此查询返回的顶级对象将是 类型Esto
。
为什么?
让我们考虑一下 Breeze 如何解释查询规范。
请注意,正如我们通常所做的那样,您通过命名将提供数据的资源来开始查询。此资源通常是到远程服务端点的路径段,可能是 Web API 控制器方法的名称……一个名为“Foos”的方法。
了解查询资源名称很少与EntityType
名称相同是至关重要的! 它们可能相似——“Foos”(复数)类似于类型名称“Foo”(单数)。但资源名称可能是别的东西。它可能是“GetFoos”或“GreatFoos”或任何东西。重要的是服务方法返回“Foo”实体。
Breeze 需要一种将资源名称与EntityType
名称相关联的方法。Breeze 本身并不知道相关性。该toType()
方法是告诉 Breeze 的一种方式。
为什么没有远程查询toType()
?
您通常不会添加toType()
到您的查询中。为什么现在?
大多数时候 [1],Breeze 不需要知道EntityType
直到数据从服务器到达之后。当 JSON 查询结果包含类型名称时(例如,当它们来自 Breeze Web API 控制器时),Breeze 可以在没有我们帮助的情况下将到达的 JSON 数据映射到实体中……假设这些类型名称在元数据中。
本地缓存查询不同
当您查询缓存时...说executeQueryLocally
... Breeze 必须知道要搜索哪个缓存实体集才能在本地查询。
它“知道”您是否使用toType()
. 但是,如果您省略toType()
,Breeze 必须使用查询的资源名称。
微风猜不透。相反,它会在 EntityType/ResourceName 映射中查找与查询资源名称匹配的实体集。
资源名称指的是服务端点,而不是缓存的实体集。例如,没有名为“Informacion”的实体集。因此 Breeze 使用EntityType/ResourceName映射来查找与查询资源名称关联的实体类型。
实体类型/资源名称
EntityType/ResourceName映射是 Breeze 中的项目之一MetadataStore
。你可能从未听说过它。那挺好的; 你不应该考虑它......除非你做一些不寻常的事情,比如定义你自己的类型。
一个新的地图MetadataStore
开始是空的。如果这些元数据包含 EntityType/Resource 映射,Breeze 会从服务器元数据中填充它。
例如,Breeze使用从名称EFContextProvider
派生的映射生成元数据。DbSet
当您定义一个Foo
类并将其从 a 公开DbContext
为DbSet
命名的“Foos”时,EFContextProvider
元数据生成器会添加从“Foos”资源名称到Foo
实体类型的映射。
控制器开发人员倾向于使用DbSet
名称作为方法名称。传统的 Breeze Web API 控制器“Foo”查询方法如下所示:
[得到]
公共 IQueryable<Foo> Foos() {...}
现在,如果您进行这样的查询:
var query = EntityQuery.from('Foos').where(...);
并将其应用于缓存
manager.query.executeLocally(query).then(...);
它只是工作。
为什么?因为
- “Foos”是
DbSet
服务器上的名称
- 生成的
EFContextProvider
元数据映射 ["Foos" 到Model.Foo
]
- Web API 控制器提供了一种
Foos
操作方法。
- BreezeJS
query
指定“Foos”
- 该
executeLocally
方法在元数据中找到 ["Foos"-to- Model.Foo
] 映射,并将查询应用于 的实体集Foo
。
端到端的约定默默地为您服务。
...直到您提到不在 EntityType/ResourceName 映射中的资源名称!
注册资源名称
没问题!
您可以添加自己的资源到实体类型的映射,如下所示:
var metadataStore = manager.metadataStore;
var typeName = '一些类型名称';
var entityType = metadataStore.getEntityType(typeName);
metadataStore.setEntityTypeForResourceName(resource, entityType);
Breeze 也对类型的名称感到满意:
metadataStore.setEntityTypeForResourceName(resource, typeName);
在你的情况下,在你的顶部附近的某个地方DataContext
,你可以写:
var metadataStore = manager.metadataStore;
// 将两个资源名称映射到 Esto
metadataStore.setEntityTypeForResourceName('Esto', 'Esto');
metadataStore.setEntityTypeForResourceName('Informacion', 'Esto');
不要过度使用toType()
当toType()
您需要将查询结果中的顶级对象映射到EntityType
. 您不必为注册资源名称而烦恼。
但是,您必须记住添加toType()
到需要它的每个查询。使用资源到实体类型的映射配置 Breeze 元数据,您每次都会获得所需的行为。
笔记
[1] “大多数时候,Breeze 不需要知道EntityType
直到数据从服务器到达之后。 ” 一个重要的例外——超出本讨论的范围——是查询过滤器涉及日期/时间时。