繁体   English   中英

如何将LINQ查询写入SQL IN

[英]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();

或者您可以使用内联WhereCount

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及其用户UserPreferenceZones位于本地内存中(而不是数据库中。这些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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM