[英]How to write LINQ query to sql IN
I want to query my cosmosDB to get List of Documents of type ZonesDO && whose id are in UserPreferance.Zones My UserPreferance class is : 我想查询我的cosmosDB以获取ZonesDO &&类型的文档列表,其ID在UserPreferance.Zones中。我的UserPreferance类是:
public class UserPreference
{
[JsonProperty("zones")]
public List<Zone> Zones { get; set; }
}
and Zone Class is: 区域类别为:
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; }
}
I am trying this query but not able to complete it. 我正在尝试此查询,但无法完成它。
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();
You can try to use Contain
method. 您可以尝试使用
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();
Or you can use inline Where
and Count
或者您可以使用内联
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();
Perform select on Zones.Id
and then check with Contains
to get desired result 在
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();
Another option may be to use the Any()
operator: 另一种选择是使用
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 providers usually understands basic methods on arrays/collections. Linq提供程序通常了解数组/集合的基本方法。 Therefore you can use
Contains
method. 因此,您可以使用
Contains
方法。
var zones = DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
.Where(z => z.Type == typeof(ZoneDO).ToString() &&
user.UserPreference.Zones.Contains(z.Id))
.AsEnumerable().ToList();
So apparently you have a user
. 因此,显然您有一个
user
。 This user
has a UserPreference
and this UserPreference
has zero or more Zones
. 该
user
具有一个UserPreference
并且此UserPreference
具有零个或多个Zones
。 It seems that this user
, and the Zones
of this user's UserPreference
is in local memory (not in a database. The Zones
are IEnumerable and not IQueryable) 看来此
user
及其用户UserPreference
的Zones
位于本地内存中(而不是数据库中。这些Zones
是IEnumerable而不是IQueryable)
Although you didn't specify, it seems that DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
returns an IQueryable<ZoneDO>
尽管您未指定,但似乎
DbUtil.Client.CreateDocumentQuery<ZoneDO>(CollectionUri)
返回IQueryable<ZoneDO>
You want all ZoneDo
that have an Id that is an Id of one of the Zones
in the one and only UserPreference
of your user. 你希望所有的
ZoneDo
有一个ID,它是在一个的ID Zones
的唯一UserPreference
您的用户。
In baby steps: 在婴儿步骤中:
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);
Until now no query is performed, nor any enumeration. 到现在为止,不执行任何查询,也不进行任何枚举。 To perform the query and return the fetched data as a
List<ZoneDO>
use .ToList()
; 要执行查询并以
List<ZoneDO>
返回获取的数据,请使用.ToList()
;
List<ZoneDO> documents = requestedZoneDOs.ToList();
TODO: if desired put all statements into one big LINQ statement. TODO:如果需要,将所有语句放入一个大LINQ语句中。 I doubt whether this will improve performance.
我怀疑这是否会提高性能。 It surely will deteriorate readability and thus maintainability.
它肯定会降低可读性,从而降低可维护性。
Did you notice that I did not do your type checking part. 您是否注意到我没有进行类型检查。 This was not needed, because function
CreateDocumentQuery<ZoneDO>
already returns a sequence f ZoneDo
. 这不是必需的,因为函数
CreateDocumentQuery<ZoneDO>
已经返回一个序列f ZoneDo
。
If not, and there are other types in the returned sequence, use OfType<ZoneDo>
instead of checking on string representation of the returned objects: 如果不是,并且返回序列中还有其他类型,请使用
OfType<ZoneDo>
而不是检查返回对象的字符串表示形式:
IQueryable<ZoneDO> allZoneDOs = DbUtil.Client
.CreateDocumentQuery<ZoneDO>(CollectionUri)
.OfType<ZoneDo>();
AsEnumerable
is not needed. 不需要
AsEnumerable
。 IQueryable.ToList()
will perform the query and convert the data to a list. IQueryable.ToList()
将执行查询并将数据转换为列表。
AsEnumerable
is only needed if you need the data in local memory to continue with LINQ statements that cannot be performed as IQueryable, like LINQ statements where you call local functions, or LINQ statements that cannot be translated into SQL. 仅当您需要本地内存中的数据才能继续无法以IQueryable身份执行的LINQ语句(例如调用本地函数的LINQ语句或无法转换为SQL的LINQ语句)时,才需要
AsEnumerable
。
AsEnumerable
will fetch the requested data per 'page'. AsEnumerable
将在每个“页面”中获取请求的数据。 So if you only need the first (few) elements, you don't fetch the complete table, but only the first (few) pages. 因此,如果仅需要前几个元素,则无需获取完整的表,而仅获取前几个页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.