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.cswith typed properties. GlideRecord fields are accessed by string name —gr.getValue('priority')notincident.Priority. It feels like working withDataRowinstead of strongly-typed entities. - Cursor-based, not collection-based: GlideRecord behaves like
SqlDataReader, notList<T>. You iterate withwhile(gr.next()), notforeach. 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-Migrationcommand. - getValue() vs dot-walking:
gr.caller_idreturns a GlideElement object (not the value). Usegr.getValue('caller_id')for the raw sys_id orgr.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.