如何将LINQ查询写入SQL IN

时间:2018-09-24 11:30:55

标签: c# linq

我想查询我的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();

5 个答案:

答案 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();

或者您可以使用内联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();

答案 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将在每个“页面”中获取请求的数据。因此,如果仅需要前几个元素,则无需获取完整的表,而仅获取前几个页面。