Sitecore:使用 LINQ 与 ID 进行比较的有效方法
Sitecore: efficient way to use LINQ to compare against an ID
我有一个 LINQ 查询检索 的列表,例如:
var results = SearchContext.GetQueryable<Person>()
.Where(i => i.Enabled)
.Where(i => i.TemplateName == "Person")
.Random(6);
每个 "Person" 类型的对象都有一个 "Location" 字段,它也是 Glass 映射项,因此有一个 ID;我只想要 select 个位置具有特定 ID 的项目。
我怎样才能以高效的方式进行此操作?
编辑:我可能应该澄清一下,我无法有效或无效地执行此比较。因为 GUID 是一个对象,我不能在 LINQ 查询中执行 ToString,所以我不能只选择 Location 项具有特定 ID 的项。关于如何实现这一目标的任何线索?
编辑 2:添加子句
.Where(i => i.Location.Id == this.Id)
不起作用,出于...某种原因,因为我无法调试什么 LINQ "sees"。如果我转换另一个 ID,我将以这种方式将其与字符串进行比较:
var theOtherID = this.Id.ToString("N");
然后它适用于此 LINQ 行:
.Where(i => i["Location"].Contains(theOtherID))
我仍然不知道为什么。
我想不出比使用简单的 where
语句更有效的方法,例如:
var results = SearchContext.GetQueryable<Person>()
.Where(i => i.Enabled && i.TemplateName == "Person" &&
i.Location != null && i.Location.Id == 1)
.Random(6);
请记住,如果对每个参数使用 &&
语句而不是 where
,则可以降低算法的复杂性。
您也可以在 Location
上使用 Inverse Navigation Property 到 virtual ICollection<Person>
,然后可以这样做:
var results = SearchContext.GetQueryable<Location>()
.Where(i => i.Id == 1 && i.Persons.Where(p => p.Enabled && p.TemplateName == "Person").Any())
.Random(6);
第一个选项仍然是最有效的,因为第二个选项使用 sub-queries
。但值得一提的是,您可以通过其他方式进行搜索。
一种方法是在 Person
上包含单独的 属性,它会被 Glass 映射器忽略,但可用于搜索:
[SitecoreIgnore]
[Sitecore.ContentSearch.IndexField("location")]
public Sitecore.Data.ID LocationID { get; set; }
您可以在搜索中使用它,如下所示:
Sitecore.Data.ID locationId = Sitecore.Data.ID.Parse(stringOrGuid);
var results = SearchContext.GetQueryable<Person>()
.Where(i => i.Enabled)
.Where(i => i.TemplateName == "Person")
.Where(i => i.LocationID == locationId)
.Random(6);
我认为使用多个 where 子句与条件语句的效率值得商榷。它们可能会导致执行相同的 Lucene 查询。在这种情况下,我更喜欢可读性而不是优化,但这就是我。
我有一个 LINQ 查询检索 的列表,例如:
var results = SearchContext.GetQueryable<Person>()
.Where(i => i.Enabled)
.Where(i => i.TemplateName == "Person")
.Random(6);
每个 "Person" 类型的对象都有一个 "Location" 字段,它也是 Glass 映射项,因此有一个 ID;我只想要 select 个位置具有特定 ID 的项目。
我怎样才能以高效的方式进行此操作?
编辑:我可能应该澄清一下,我无法有效或无效地执行此比较。因为 GUID 是一个对象,我不能在 LINQ 查询中执行 ToString,所以我不能只选择 Location 项具有特定 ID 的项。关于如何实现这一目标的任何线索?
编辑 2:添加子句
.Where(i => i.Location.Id == this.Id)
不起作用,出于...某种原因,因为我无法调试什么 LINQ "sees"。如果我转换另一个 ID,我将以这种方式将其与字符串进行比较:
var theOtherID = this.Id.ToString("N");
然后它适用于此 LINQ 行:
.Where(i => i["Location"].Contains(theOtherID))
我仍然不知道为什么。
我想不出比使用简单的 where
语句更有效的方法,例如:
var results = SearchContext.GetQueryable<Person>()
.Where(i => i.Enabled && i.TemplateName == "Person" &&
i.Location != null && i.Location.Id == 1)
.Random(6);
请记住,如果对每个参数使用 &&
语句而不是 where
,则可以降低算法的复杂性。
您也可以在 Location
上使用 Inverse Navigation Property 到 virtual ICollection<Person>
,然后可以这样做:
var results = SearchContext.GetQueryable<Location>()
.Where(i => i.Id == 1 && i.Persons.Where(p => p.Enabled && p.TemplateName == "Person").Any())
.Random(6);
第一个选项仍然是最有效的,因为第二个选项使用 sub-queries
。但值得一提的是,您可以通过其他方式进行搜索。
一种方法是在 Person
上包含单独的 属性,它会被 Glass 映射器忽略,但可用于搜索:
[SitecoreIgnore]
[Sitecore.ContentSearch.IndexField("location")]
public Sitecore.Data.ID LocationID { get; set; }
您可以在搜索中使用它,如下所示:
Sitecore.Data.ID locationId = Sitecore.Data.ID.Parse(stringOrGuid);
var results = SearchContext.GetQueryable<Person>()
.Where(i => i.Enabled)
.Where(i => i.TemplateName == "Person")
.Where(i => i.LocationID == locationId)
.Random(6);
我认为使用多个 where 子句与条件语句的效率值得商榷。它们可能会导致执行相同的 Lucene 查询。在这种情况下,我更喜欢可读性而不是优化,但这就是我。