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 Propertyvirtual 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 查询。在这种情况下,我更喜欢可读性而不是优化,但这就是我。