我想查询我的cosmosDB以获取ID为UserPreferance的ZonesDO &&类型的文档列表。Zones我的UserPreferance类为:
public class UserPreference
{
[JsonProperty("zones")]
public List<Zone> Zones { get; set; }
}
和区域类别为:
public class Zone
{
[JsonProperty("id")]
public override Guid Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("category")]
public string Category { get; set; }
}
我正在尝试查询,但无法完成。
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
*z.Id in user.UserPreference.Zones.ids*)// here I need the solution
.AsEnumerable().ToList();
答案 0 :(得分:1)
您可以尝试使用Contain
方法。
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Select(x => x.Id).Contain(z.Id)).ToList();
或者您可以使用内联Where
和Count
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(
z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Where(a=> a.Id == z.Id).Count() > 0
).ToList();
答案 1 :(得分:1)
在Zones.Id
上进行选择,然后与Contains
核对以获得所需结果
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Select(x => x.Id).Contains(z.Id))
.AsEnumerable().ToList();
答案 2 :(得分:1)
另一种选择是使用Any()
运算符:
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Where(x => x.Id == z.Id).Any())
.AsEnumerable().ToList();
答案 3 :(得分:0)
Linq提供程序通常了解数组/集合的基本方法。因此,您可以使用Contains
方法。
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Contains(z.Id))
.AsEnumerable().ToList();
答案 4 :(得分:0)
因此,显然您有一个user
。该user
有一个UserPreference
,这个UserPreference
有零个或多个Zones
。看来此user
和该用户Zones
的{{1}}在本地内存中(不在数据库中。UserPreference
是IEnumerable而不是IQueryable)
尽管您未指定,但似乎Zones
返回了DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
您希望所有IQueryable<ZoneDO>
的ID都是您的一个ZoneDo
用户中唯一Zones
之一的ID。
在婴儿步骤中:
UserPreference
直到现在,不执行查询,也不进行任何枚举。要执行查询并以IEnumerable<Guid> zoneIds = user.Userpreference.Zones.Select(zone => zone.Id);
IQueryable<ZoneDO> allZoneDOs = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri);
IEnumerable<ZoneDO> requestedZoneDOs = allZoneDOs
.Where(zoneDo => zoneIds.Contains(zoneDo.Id);
的形式返回获取的数据,请使用List<ZoneDO>
;
.ToList()
TODO:如果需要,将所有语句放入一个大的LINQ语句中。我怀疑这是否会提高性能。它肯定会降低可读性,从而降低可维护性。
您是否注意到我没有进行类型检查。不需要这样做,因为函数List<ZoneDO> documents = requestedZoneDOs.ToList();
已返回序列f CreateDocumentQuery<ZoneDO>
。
如果没有,并且返回的序列中还有其他类型,请使用ZoneDo
而不是检查返回对象的字符串表示形式:
OfType<ZoneDo>
不需要 IQueryable<ZoneDO> allZoneDOs = DbUtil.Client
.CreateDocumentQuery<ZoneDO>(CollectionUri)
.OfType<ZoneDo>();
。 AsEnumerable
将执行查询并将数据转换为列表。
IQueryable.ToList()
仅在需要本地内存中的数据才能继续无法以IQueryable身份执行的LINQ语句(如调用本地函数的LINQ语句或无法转换为SQL的LINQ语句)时才需要。
AsEnumerable
将在每个“页面”中获取请求的数据。因此,如果仅需要前几个元素,则无需获取完整的表,而仅获取前几个页面。