[英]How to write LINQ query to sql IN
我想查询我的cosmosDB以获取ZonesDO &&类型的文档列表,其ID在UserPreferance.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();
您可以尝试使用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();
在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();
另一种选择是使用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();
Linq提供程序通常了解数组/集合的基本方法。 因此,您可以使用Contains
方法。
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Contains(z.Id))
.AsEnumerable().ToList();
因此,显然您有一个user
。 该user
具有一个UserPreference
并且此UserPreference
具有零个或多个Zones
。 看来此user
及其用户UserPreference
的Zones
位于本地内存中(而不是数据库中。这些Zones
是IEnumerable而不是IQueryable)
尽管您未指定,但似乎DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
返回IQueryable<ZoneDO>
你希望所有的ZoneDo
有一个ID,它是在一个的ID Zones
的唯一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()
;
List<ZoneDO> documents = requestedZoneDOs.ToList();
TODO:如果需要,将所有语句放入一个大LINQ语句中。 我怀疑这是否会提高性能。 它肯定会降低可读性,从而降低可维护性。
您是否注意到我没有进行类型检查。 这不是必需的,因为函数CreateDocumentQuery<ZoneDO>
已经返回一个序列f ZoneDo
。
如果不是,并且返回序列中还有其他类型,请使用OfType<ZoneDo>
而不是检查返回对象的字符串表示形式:
IQueryable<ZoneDO> allZoneDOs = DbUtil.Client
.CreateDocumentQuery<ZoneDO>(CollectionUri)
.OfType<ZoneDo>();
不需要AsEnumerable
。 IQueryable.ToList()
将执行查询并将数据转换为列表。
仅当您需要本地内存中的数据才能继续无法以IQueryable身份执行的LINQ语句(例如调用本地函数的LINQ语句或无法转换为SQL的LINQ语句)时,才需要AsEnumerable
。
AsEnumerable
将在每个“页面”中获取请求的数据。 因此,如果仅需要前几个元素,则无需获取完整的表,而仅获取前几个页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.