不支持使用breeze在同一查询中执行选择和展开

不支持使用breeze在同一查询中执行选择和展开,breeze,durandal,Breeze,Durandal,我用Durandal/breeze开发了一个asp.net解决方案 以下是我获取所有托运人的代码: var query = EntityQuery.from('Shippers') .select('id, name, street, city'); return manager.executeQuery(query) .then(querySucceeded) .fail(queryFailed); 以下是相关模型: publi

我用Durandal/breeze开发了一个asp.net解决方案

以下是我获取所有托运人的代码:

var query = EntityQuery.from('Shippers')
               .select('id, name, street, city');

return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);
以下是相关模型:

public class Shipper
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Street { get; set; }
    public string Number { get; set; }
    public City City { get; set; }
}

public class City
{
    public int Id { get; set; }        
    public string Name { get; set; }
    public string PostCode { get; set; }
    public Country Country { get; set; }
}
现在我还需要包括国家

public class Country
{
    [Key]
    public int Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
}
但就实际问题而言,我没有得到国家的支持

我尝试:

var query = EntityQuery.from('Shippers')
               .select('id, name, street, city')
               .expand('City.Country');
但我得到了一个错误:

当前不支持在同一查询中同时使用“展开”和“选择”

我的问题:如何获得国家


更新

正如Jay所建议的,我们可以:

var query = EntityQuery.from('Shippers')
       .select('id, name, street, city, city.country')
现在,我得到了一个
city\u Country
对象:

我不明白为什么我们得到这个
城市\国家
,因为国家数据已经在城市\国家对象中可用:

此外,这给了我一个问题,因为我的下一个语句试图将我的dto映射到我的实体中,而我的实体中不存在此
城市\国家
对象,并且映射时发生错误

下面我们看到我的实体对象,没有
city\u Country
对象:

我必须在映射上做一些特殊的操作来避免它吗

下面是映射操作的函数:

function mapToEntity(entity, dto) {
     // entity is an object with observables
     // dto is from json
     for (var prop in dto) {
          if (dto.hasOwnProperty(prop)) {
             entity[prop](dto[prop]);
          }
     }
     return entity;
}
我们允许这样做:

var query = EntityQuery.from('Shippers')
           .select('id, name, street, city, city.country')

我不确定使用投影来“部分”填充实体是否是一种好的做法,这看起来就像您正在做的事情。Breeze将自动映射它在结果集中找到的任何真实“实体”。那么,为什么不简单地使用

var query = EntityQuery.from('Shippers')
    .where(...)
    .expand('city.country');
即时结果将是托运人的集合,但每个托运人也将拥有其城市和嵌套国家属性作为实体进行完全解析。它们将通过返回的托运人的导航可用,但如果您想直接查询它们,它们也将在entityManager缓存中可用

第二个注意事项:“扩展”语义与实体框架具有相同的限制。这意味着我们无法展开投影的属性

因此,您可以跳过投影(如上所述)

并获得完整的“托运人”实体,该城市的“城市”和“国家”属性均已填充……或者您可以进行预测,在这种情况下,您自己执行扩展的等效操作

在这种情况下,您将

var query = EntityQuery.from('Shippers')
  .select('id, name, street, city, city.country')
在这种情况下,结果集中的每个项目将由5个属性组成。请注意,在这种情况下,只有“city”和“city.country”属性将添加到entityManager的缓存中,因为它们是结果集中唯一的“true”实体。即,没有发货人的属性

需要明确的是,查询的“结果”和查询的“副作用”是不同的。查询的顶级结果将完全是您期望的形状。查询的“副作用”是您执行的任何“扩展”的结果。这些不会更改查询的形式,只会更改任何嵌套查询的分辨率结果中的“实体”属性


希望这能有所帮助。

我更新了我的问题以显示结果。你能看一下吗?谢谢。对一对多属性执行此操作不会有任何效果,例外消息:“无法在类型'System.Collections.Generic.ICollection`1[Domain.Entities.UserProfile]'上找到属性'UserName'。“,谢谢你的解释。我之所以在查询中使用投影,是因为某些实体可能包含许多“重”属性,如图像。。。因此,在查询简单列表的情况下,最好只获取必要的属性还是实体的所有属性?一个选项是简单地将“重”属性映射到它们自己的EntityType,并与“父类型”一一对应,这将排除它们。另一种方法是实际测量使用“完整”实体的性能/内存占用,看看它们是否像您想象的那样昂贵。我将从最简单的体系结构开始,只有当您向自己证明它不具备性能时,才会对其进行复杂化/优化。i、 不要过早优化。
var query = EntityQuery.from('Shippers')
  .select('id, name, street, city, city.country')