‹ All interview questions

Core Concepts

You've spent 12 years building .NET applications with Entity Framework.

The question

You've spent 12 years building .NET applications with Entity Framework. Your new team tells you ServiceNow uses 'GlideRecord' to interact with data. Walk me through how GlideRecord compares to what you already know — DbContext, LINQ queries, and EF migrations. What would surprise you the most coming from that world?

Why This Matters in an Interview

This question tests whether a seasoned .NET developer can mentally map their existing ORM knowledge to ServiceNow's server-side data API. Interviewers want to see that you're not starting from zero — you're translating.

The Direct Mapping

GlideRecord is ServiceNow's server-side API for database operations. If Entity Framework is your ORM that abstracts SQL into C# objects, GlideRecord is the equivalent abstraction layer — but with key differences:

// .NET Entity Framework (what you know)
var incidents = dbContext.Incidents
  .Where(i => i.Priority == 1 && i.State == "New")
  .OrderByDescending(i => i.CreatedOn)
  .Take(10)
  .ToList();

// ServiceNow GlideRecord (the equivalent)
var gr = new GlideRecord('incident');
gr.addQuery('priority', 1);
gr.addQuery('state', 'New');
gr.orderByDesc('sys_created_on');
gr.setLimit(10);
gr.query();
while (gr.next()) {
  // Each gr.next() moves the cursor — like a DataReader
  gs.info(gr.getValue('number'));
}

What Surprises .NET Developers

  • No model classes: There's no Incident.cs with typed properties. GlideRecord fields are accessed by string name — gr.getValue('priority') not incident.Priority. It feels like working with DataRow instead of strongly-typed entities.
  • Cursor-based, not collection-based: GlideRecord behaves like SqlDataReader, not List<T>. You iterate with while(gr.next()), not foreach. There's no .ToList() that materializes everything into memory.
  • No migrations: Schema changes happen through the UI or Update Sets — not code-first migrations. Adding a column to a table is a point-and-click operation, not an Add-Migration command.
  • getValue() vs dot-walking: gr.caller_id returns a GlideElement object (not the value). Use gr.getValue('caller_id') for the raw sys_id or gr.getDisplayValue('caller_id') for the display name — similar to how EF navigation properties vs foreign key IDs work.
💡 .NET Developer Pro Tip

Think of GlideRecord as ADO.NET's DataReader wrapped with a query builder. It's not as elegant as LINQ, but the mental model is identical: build a query, execute it, iterate results. Your instincts about N+1 queries, limiting result sets, and indexing all transfer directly.