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