Search code examples
c#linqsitecoreglass-mapper

Sitecore: efficient way to use LINQ to compare against an ID


I have a LINQ query retrieving a list of , such as this:

var results = SearchContext.GetQueryable<Person>()
  .Where(i => i.Enabled)
  .Where(i => i.TemplateName == "Person")
  .Random(6);

Each object of type "Person" has a "Location" field which is also a Glass mapped item, and hence has an ID; I would like to only select items whose Location has a specific ID.

How can I go about doing this in an efficient manner?

EDIT: I should probably clarify that I am unable to perform this comparison, efficiently or not. Because the GUID is an object and I cannot perform ToString in a LINQ query, I am unable to only pick the items whose Location item has a specific ID. Any clues on how this could be achieved?

EDIT 2: Adding the clause

.Where(i => i.Location.Id == this.Id)

Doesn't work, for... some reason, as I'm unable to debug what LINQ "sees". If I convert the other ID I'm comparing it against to string this way:

var theOtherID = this.Id.ToString("N");

Then it works with this LINQ line:

.Where(i => i["Location"].Contains(theOtherID))

I still have no idea why.


Solution

  • One approach is to include a separate property on Person that is ignored by Glass mapper, but can be used in searches:

    [SitecoreIgnore]
    [Sitecore.ContentSearch.IndexField("location")]
    public Sitecore.Data.ID LocationID { get; set; }
    

    You can use this in your search as follows:

    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);
    

    I think the efficiency of using multiple where clauses vs. conditionals is debatable. They will likely result in the same Lucene query being performed. I would prefer readability over optimization in this instance, but that's just me.