70 Entity Framework Core Interview Questions and Answers (2026)

Blog / 70 Entity Framework Core Interview Questions and Answers (2026)
Entity Framework Core

Entity Framework Core is the default data layer for modern .NET, and interviewers expect real fluency with it, not buzzwords. Knowing the syntax isn't enough: walk in shaky on change tracking, loading strategies, or N+1 traps and a sharp interviewer will spot it in minutes.

This post gives you 70 questions with tight, interview-ready answers and code where it matters. They're ordered Junior → Mid → Senior, so you build from DbContext basics to interceptors, concurrency, and performance tuning. Work through them in order and you'll know exactly what to say when it counts.

Q1.
What is the role of the DbContext in EF Core, and what patterns does it implement?

Junior

The DbContext is the central object that represents a session with the database: it tracks entities, translates LINQ to SQL, and coordinates persisting changes. It is your gateway to querying and saving data.

  • Core responsibilities:

    • Exposes DbSet<T> properties for querying and the change tracker for entity state.

    • Manages the database connection, model/metadata, and translates LINQ into provider SQL.

    • Persists tracked changes in one batch when you call SaveChanges().

  • Patterns it implements:

    • Unit of Work: tracks all changes and commits them together in a single SaveChanges (one transaction).

    • Repository: each DbSet<T> acts as a queryable repository over an entity type.

  • Lifetime matters: It is not thread-safe and is meant to be short-lived (typically scoped per request/operation).

Q2.
What is the difference between DbContext and DbSet?

Junior

The DbContext represents the whole database session and unit of work, while a DbSet<T> represents a single queryable collection of one entity type (usually mapped to one table) within that context.

  • DbContext:

    • Owns the connection, model, change tracker, and SaveChanges().

    • Contains one or more DbSet<T> properties.

  • DbSet<T>:

    • An IQueryable<T> entry point for querying entities of type T.

    • Provides Add, Remove, Find, etc., but actual persistence happens via the context's SaveChanges().

  • Analogy: The context is the database; each DbSet is a table.

Q3.
Explain the difference between IQueryable<T> and IEnumerable<T> specifically regarding where the query execution happens.

Junior

With IQueryable<T> the query is translated to SQL and executed in the database; with IEnumerable<T> the data is already in memory and any further operations run in-process with LINQ to Objects.

  • IQueryable<T>:

    • Builds an expression tree that the EF provider translates to SQL.

    • Filtering/projection (Where, Select) happens server-side, so only needed rows/columns are returned.

  • IEnumerable<T>:

    • Operates on objects already pulled into memory; further LINQ runs in the app.

    • Composing filters after switching to it cannot reduce what was fetched from the DB.

  • The common trap: Calling AsEnumerable(), ToList(), or a non-translatable method too early forces the whole table into memory before filtering.

  • Rule of thumb: keep the query as IQueryable<T> until all server-side filtering is applied, then materialize.

Q4.
What is the purpose of AsNoTracking(), and what are the tradeoffs of using it?

Junior

AsNoTracking() tells EF Core not to track the returned entities in the change tracker, making read-only queries faster and lighter. The tradeoff is you lose change tracking and identity resolution, so those entities can't be updated directly and duplicates may be materialized.

  • What it does:

    • Skips creating tracking snapshots, so less memory and CPU per query.

    • Ideal for read-only data you'll display but never modify.

  • Tradeoffs:

    • Calling SaveChanges() won't persist edits to untracked entities (EF doesn't know about them).

    • By default no identity resolution: the same row referenced twice can become two object instances. Use AsNoTrackingWithIdentityResolution() if you need de-duplication.

  • Tips:

    • You can set it as the context default via QueryTrackingBehavior.NoTracking.

    • Use tracking queries when you intend to update entities.

Q5.
What is 'Deferred Execution' and when does a query actually hit the database?

Junior

Deferred execution means building an IQueryable<T> doesn't run anything: the query only executes when you actually enumerate or materialize the results. This lets you compose a query in pieces before a single SQL statement is sent.

  • When it executes (hits the DB):

    • Materializing: ToList(), ToArray(), ToDictionary().

    • Single-value aggregates/scalars: Count(), First(), Any(), Sum().

    • Iterating with foreach or their async equivalents (ToListAsync()).

  • What stays deferred: Composition operators (Where, OrderBy, Select) just build the expression tree.

  • Why it matters:

    • Re-enumerating an IQueryable runs the SQL again each time; materialize once if you need to reuse results.

    • Beware enumerating after the DbContext is disposed.

Q6.
What is the difference between a 'Projected' query using .Select() and returning the full entity?

Junior

Returning the full entity loads all mapped columns and (by default) tracks it, while a projection with .Select() pulls only the specific columns/shape you ask for. Projections are leaner and read-only; full entities are needed when you intend to update them.

  • Full entity:

    • SELECTs every mapped column even if unused.

    • Tracked by default, so it can be modified and saved with SaveChanges().

  • Projected query (.Select()):

    • Generates SQL that fetches only the chosen columns: less data over the wire.

    • Result (anonymous type or DTO) is not tracked, so it can't be directly updated.

    • Can flatten related data into the shape you need, reducing over-fetching and N+1.

  • Rule of thumb: project for read/display scenarios (especially APIs); load full entities when you need to mutate and persist them.

csharp

// Projection: only two columns selected in SQL, untracked var list = context.Blogs .Select(b => new { b.Id, b.Title }) .ToList();

Q7.
What is the difference between First/Single/FirstOrDefault/SingleOrDefault in EF Core queries and how do they affect the generated SQL?

Junior

All four return a single entity, but they differ in how they handle zero or multiple matches, and that difference changes the SQL EF Core emits: the Single variants fetch up to two rows to detect duplicates, while the First variants fetch only one.

  • First(): Returns the first match; throws if none. SQL uses TOP(1) (or LIMIT 1).

  • FirstOrDefault(): Same TOP(1) SQL but returns null/default when there are no rows.

  • Single(): Requires exactly one match; throws on zero or more than one. SQL uses TOP(2) so EF can detect a second row and throw.

  • SingleOrDefault(): Also fetches TOP(2); returns default for zero rows but still throws if more than one.

  • Choosing: Use the Single forms to assert uniqueness (e.g. by primary key) and catch data bugs; use First when you expect possibly many and just want one, ideally with OrderBy for determinism.

Q8.
What conventions does EF Core use to discover primary keys, foreign keys, and table names in code-first?

Junior

EF Core uses naming and type conventions to infer the model so you only configure exceptions. It recognizes primary keys, foreign keys, and table names from property and class names automatically.

  • Primary keys:

    • A property named Id or <TypeName>Id (e.g. BlogId) is treated as the PK.

    • Numeric or GUID keys get value generation (identity) by convention.

  • Foreign keys:

    • A navigation plus a property like <Navigation>Id, <PrincipalType>Id, or <PrincipalType><PrincipalKey> is mapped as the FK.

    • Nullability of the FK property controls whether the relationship is optional or required.

  • Table and column names:

    • Table name defaults to the DbSet<T> property name; if none, the entity class name.

    • Column names default to property names; column type maps from the CLR type via the provider.

  • Override when needed: Conventions are just defaults: use annotations or Fluent API (ToTable, HasKey, HasForeignKey) to override.

Q9.
How do you configure property mappings such as column names, data types, max length, and required/nullable in EF Core?

Junior

Configure property mappings via the Fluent API in OnModelCreating (or Data Annotations) using methods like HasColumnName, HasColumnType, HasMaxLength, and IsRequired. Fluent config wins when both are present and keeps mapping out of your domain classes.

  • Column name and type:

    • HasColumnName("...") renames the column; HasColumnType("decimal(18,2)") sets the exact store type.

    • Use HasPrecision(18, 2) as a provider-agnostic alternative for decimals.

  • Length: HasMaxLength(200) maps to e.g. nvarchar(200); omitting it produces nvarchar(max).

  • Required vs nullable:

    • IsRequired() makes the column NOT NULL; IsRequired(false) makes it nullable.

    • With nullable reference types enabled, a non-nullable C# type (string) is inferred as required automatically.

  • Annotations vs Fluent:

    • Annotations: [Column], [MaxLength], [Required] are simpler but live on the entity.

    • Fluent API is more expressive and centralizes configuration; it overrides conflicting annotations.

csharp

modelBuilder.Entity<Product>(b => { b.Property(p => p.Name) .HasColumnName("ProductName") .HasMaxLength(200) .IsRequired(); b.Property(p => p.Price) .HasColumnType("decimal(18,2)"); });

Q10.
Describe the different EntityState values (Added, Modified, Deleted, Unchanged, Detached) and how they affect SaveChanges.

Junior

EntityState tells the Change Tracker what SQL (if any) to emit for an entity on SaveChanges: Added inserts, Modified updates, Deleted deletes, while Unchanged and Detached produce nothing.

  • Added: New entity not yet in the DB; SaveChanges issues an INSERT and populates generated keys.

  • Modified: Tracked entity with changed values; emits an UPDATE (by default only for the changed columns).

  • Deleted: Marked for removal; emits a DELETE. After save it becomes Detached.

  • Unchanged: Tracked but matches its snapshot; ignored by SaveChanges. This is the default state for entities loaded from a query.

  • Detached: Not tracked by the context at all; the Change Tracker knows nothing about it, so it is never persisted until attached/added.

Q11.
What is the purpose of the __EFMigrationsHistory table?

Junior

The __EFMigrationsHistory table is EF Core's ledger inside the database that records which migrations have already been applied, so EF knows which ones are still pending.

  • Contents: One row per applied migration, with MigrationId (timestamped name) and ProductVersion (the EF Core version used).

  • How it's used:

    • On Database.Migrate() or dotnet ef database update, EF reads this table and applies only migrations not yet present.

    • Applying adds a row; reverting removes it.

  • Practical notes: It's auto-created in the database's default schema; it ensures migrations are idempotent and not re-run.

Q12.
How do you add, apply, revert, and remove migrations using the EF Core tooling?

Junior

You manage migrations with the EF Core tooling, available as the .NET CLI (dotnet ef) or the Package Manager Console cmdlets. The four core operations are add, apply (update database), revert (update to an earlier migration), and remove the last migration.

  • Add a migration: dotnet ef migrations add <Name> scaffolds an Up/Down migration and updates the model snapshot.

  • Apply migrations: dotnet ef database update applies all pending migrations; database update <Name> goes to a specific one.

  • Revert migrations: Run database update <PreviousMigration> to roll the DB back (runs Down methods); use 0 to undo all.

  • Remove a migration: dotnet ef migrations remove deletes the last migration and reverts the snapshot, only if it hasn't been applied to the DB.

  • PMC equivalents: Add-Migration, Update-Database, Remove-Migration.

bash

dotnet ef migrations add AddOrders dotnet ef database update dotnet ef database update PreviousMigrationName # revert dotnet ef migrations remove # if not applied

Q13.
Compare EF Core to a micro-ORM like Dapper. In what scenarios would you choose one over the other?

Mid

EF Core is a full ORM with change tracking, LINQ querying, and migrations; Dapper is a thin micro-ORM that just maps raw SQL results to objects. Choose EF Core for productivity and rich domain modeling, Dapper for maximum control and raw read performance.

  • EF Core strengths:

    • Change tracking, automatic SQL generation, relationship/navigation handling, migrations, and LINQ.

    • Great for CRUD-heavy apps and complex object graphs where you want to think in objects, not SQL.

  • Dapper strengths:

    • You write the SQL; it maps rows to POCOs with minimal overhead, so it's very fast and predictable.

    • Ideal for hot read paths, complex hand-tuned queries, reporting, or stored-procedure-heavy work.

  • Trade-offs:

    • EF Core adds abstraction and overhead and can generate suboptimal SQL if misused.

    • Dapper means writing and maintaining SQL by hand and managing inserts/updates yourself.

  • In practice they coexist: Many teams use EF Core for writes/domain logic and Dapper for performance-critical reads.

Q14.
Explain the Repository Pattern and Unit of Work in the context of EF Core. Does DbContext already implement these?

Mid

The Repository pattern abstracts data access for a collection of entities, and Unit of Work groups multiple changes into a single atomic commit. EF Core's DbContext already implements both: DbSet<T> is a repository and the context itself is the unit of work.

  • Repository pattern:

    • Provides a collection-like interface (Add, Remove, query) for an aggregate/entity, hiding query details.

    • EF equivalent: DbSet<T> with LINQ.

  • Unit of Work:

    • Tracks changes across repositories and commits them in one transaction.

    • EF equivalent: change tracker + SaveChanges().

  • So why add your own?:

    • To centralize/standardize queries, decouple domain from EF, or aid testing.

    • Risks: wrapping DbContext can leak abstractions, hide LINQ power, and just duplicate what EF already does.

  • Common stance: A generic repository over EF is often redundant; a focused repository per aggregate can still add value in DDD designs.

Q15.
What are the primary differences between EF Core and Classic EF6?

Mid

EF Core is a lightweight, cross-platform rewrite of Entity Framework, not just a new version of EF6. It runs on .NET Core/.NET 5+, is more modular and performant, but historically lacked some EF6 features.

  • Platform and architecture: EF Core is cross-platform and modular (provider-based); EF6 is Windows/.NET Framework focused.

  • New EF Core capabilities: Better performance, LINQ improvements, batched SaveChanges, shadow properties, value conversions, HasQueryFilter (global filters), and providers for many databases.

  • Features EF6 had that EF Core added later or differently: No EDMX/designer model in EF Core; lazy loading, many-to-many, and TPT/TPC mapping arrived in later EF Core releases.

  • Querying difference: EF Core stopped automatic client-side evaluation of unsupported expressions; it now throws instead of silently running in memory.

  • Takeaway: For new apps use EF Core; EF6 mainly survives in legacy .NET Framework projects.

Q16.
What are the primary differences between the InMemory provider and a real relational provider like SQL Server when writing unit tests?

Mid

The InMemory provider is a simple in-process store, not a relational database, so it does not enforce relational behavior and can let tests pass that would fail against SQL Server. For realistic tests, prefer a real provider (or SQLite in-memory) over the EF InMemory provider.

  • No real SQL or relational semantics: It doesn't translate LINQ to SQL, so provider-specific query behavior and SQL-only functions aren't exercised.

  • No constraint enforcement: Ignores foreign keys, unique constraints, NOT NULL, and max length; invalid data may save fine.

  • No transactions: Transaction APIs are essentially no-ops, so rollback behavior isn't tested.

  • Different concurrency and key generation behavior: Concurrency tokens and identity/sequence semantics differ from a real database.

  • Recommendation: Microsoft now suggests SQLite in-memory (real relational engine) for closer fidelity, or integration tests against the actual provider.

Q17.
What database providers does EF Core support, and how do provider differences affect your code and queries?

Mid

EF Core uses a pluggable provider model: each database has its own NuGet provider that implements the SQL translation and feature support. Most code is provider-agnostic, but behavior, supported functions, and type mappings can differ, so queries aren't always perfectly portable.

  • Common providers: SQL Server (Microsoft.EntityFrameworkCore.SqlServer), PostgreSQL (Npgsql), SQLite, MySQL/MariaDB (Pomelo), Oracle, Cosmos DB, and the InMemory test provider.

  • How differences show up:

    • Type mapping: e.g. how decimal, DateTime, and GUIDs map varies by database.

    • Function translation: a LINQ call may translate on one provider but not another (e.g. certain string or date functions).

    • Feature support: sequences, computed columns, JSON columns, and some mapping strategies differ.

    • Migrations generate provider-specific SQL.

  • Practical impact: You can swap providers for most code, but always test and generate migrations against the provider you actually deploy to.

Q18.
Explain the difference between Single Query and Split Query execution. When should you use AsSplitQuery()?

Mid

A single query loads an entity and all its included collections in one SQL statement using JOINs, while a split query issues separate SQL statements (one per included collection). Use AsSplitQuery() when JOINs cause a Cartesian explosion that bloats the result set.

  • Single Query (default):

    • Joins parent and children into one statement; one round trip to the DB.

    • Problem: including multiple collections multiplies rows (Cartesian explosion), duplicating parent data many times.

  • Split Query:

    • Each included collection runs as its own SQL query; EF stitches results together.

    • Avoids row duplication but costs multiple round trips.

  • Use AsSplitQuery() when: You Include() several one-to-many collections and see a huge, duplicated result set.

  • Caveat: split queries run in separate transactions by default, so data could change between them (no full consistency unless wrapped in a transaction).

  • Configure globally or per query; the global default can be set in UseSqlServer(... o => o.UseQuerySplittingBehavior(...)).

csharp

var blogs = context.Blogs .Include(b => b.Posts) .Include(b => b.Contributors) .AsSplitQuery() .ToList();

Q19.
Explain the 'N+1 Query Problem.' How do you identify it and what are the primary ways to resolve it in EF Core?

Mid

The N+1 problem is when EF runs one query to load N parent rows, then one extra query per parent to load its related data, producing N+1 round trips instead of one efficient query. It usually comes from lazy loading or looping over entities and touching navigation properties.

  • How it happens: You fetch a list, then access a navigation (e.g. blog.Posts) inside a loop, triggering a query each iteration.

  • How to identify it:

    • Enable EF logging or use a profiler and watch for repeated, near-identical parameterized SELECTs.

    • Tools like MiniProfiler or the SQL Server Profiler make the burst of queries obvious.

  • How to resolve it:

    • Eager load with Include() / ThenInclude() to fetch related data up front.

    • Project only what you need with Select() so EF generates a single JOIN.

    • Disable lazy loading to avoid accidental per-access queries.

csharp

// N+1: one query per blog's posts var blogs = context.Blogs.ToList(); foreach (var b in blogs) Console.WriteLine(b.Posts.Count); // triggers a query each loop // Fixed: single query with eager loading var blogs = context.Blogs.Include(b => b.Posts).ToList();

Q20.
Compare Eager Loading, Explicit Loading, and Lazy Loading. What are the tradeoffs of each?

Mid

All three are ways to load related data. Eager loading fetches related data with the main query, explicit loading fetches it later on demand via an API call, and lazy loading fetches it automatically the moment you access a navigation property.

  • Eager Loading (Include()):

    • Loads related data in the same round trip; predictable and avoids N+1.

    • Tradeoff: can over-fetch or cause Cartesian explosion with multiple collections.

  • Explicit Loading (Entry().Collection()/Reference().Load()):

    • You decide exactly when to load related data, optionally filtered.

    • Tradeoff: extra explicit round trips; more verbose code.

  • Lazy Loading (proxies):

    • Related data loads transparently on first access to the navigation.

    • Convenient but the main source of accidental N+1; requires proxies and virtual navigations, and fails if the context is disposed.

  • Rule of thumb: prefer eager (or projection) for known needs, explicit for conditional/occasional loads, and avoid lazy in performance-sensitive paths.

Q21.
When would you use FromSqlRaw or FromSqlInterpolated instead of standard LINQ queries?

Mid

Use FromSqlRaw or FromSqlInterpolated when LINQ can't express what you need or you want full control over the SQL: stored procedures, vendor-specific syntax, complex queries, or performance hints. Prefer FromSqlInterpolated because it safely parameterizes interpolated values.

  • Good use cases:

    • Calling stored procedures or table-valued functions.

    • Complex SQL (advanced window functions, hints, CTEs) that LINQ can't translate well.

    • Performance-critical hand-tuned queries.

  • Safety: raw vs interpolated:

    • FromSqlInterpolated turns interpolated holes into SQL parameters, preventing injection.

    • FromSqlRaw requires you to pass parameters explicitly; never concatenate user input.

  • Constraints:

    • The query must return columns matching the entity (or a mapped type).

    • You can still compose LINQ on top (Where, Include) since it returns IQueryable<T>.

csharp

// Safe: values become parameters var blogs = context.Blogs .FromSqlInterpolated($"SELECT * FROM Blogs WHERE Rating > {minRating}") .Where(b => b.IsActive) // composes server-side .ToList();

Q22.
Why is Lazy Loading often discouraged in high-performance web applications?

Mid

Lazy loading defers loading related data until a navigation property is accessed, which is convenient but easily triggers the N+1 query problem and hidden round-trips that destroy throughput under load.

  • It causes the N+1 problem: Iterating a list of parents and touching a navigation triggers one extra query per row: 1 + N queries instead of 1 join.

  • Queries are hidden and implicit: A property access that looks like a memory read silently hits the database, making performance hard to reason about or spot in code review.

  • It needs a tracking context that stays alive: Proxies require the DbContext to still be open; in a short-lived web request you risk ObjectDisposedException or serialization-time lazy loads.

  • Preferred alternatives: Eager loading with Include(), or explicit/projected loading with Select(), give predictable, controllable SQL.

Q23.
How do you perform Eager Loading for nested relationships, such as loading a collection within a collection?

Mid

You chain Include() with ThenInclude(): Include() loads the first-level navigation, and each subsequent ThenInclude() drills into the next level, including a collection nested inside a collection.

  • Start the chain with Include() for the top navigation, then ThenInclude() for each deeper level.

  • Collection within a collection: After including a collection, ThenInclude() operates on the element type of that collection, so you keep navigating naturally.

  • Multiple branches: To include sibling navigations, start a fresh Include() call for each branch.

  • Watch for cartesian explosion: Including several collections multiplies rows; use AsSplitQuery() to emit separate SQL queries instead of one huge join.

csharp

var blogs = context.Blogs .Include(b => b.Posts) .ThenInclude(p => p.Comments) .ThenInclude(c => c.Author) .AsSplitQuery() .ToList();

Q24.
What is the difference between Include and ThenInclude, and how do filtered includes work?

Mid

Include() loads a navigation directly off the root entity, while ThenInclude() loads a navigation off the previously included entity; filtered includes let you constrain or order the related collection inline.

  • Include(): Specifies a related navigation on the query root (e.g. Blog.Posts).

  • ThenInclude(): Continues from the last included entity to go one level deeper (e.g. Post.Comments).

  • Filtered includes:

    • You can apply Where, OrderBy, Skip, and Take inside an Include() to load only a subset of the collection.

    • Only those operators are allowed, and the same filter must be used consistently if the navigation is included more than once.

csharp

var blogs = context.Blogs .Include(b => b.Posts.Where(p => p.IsPublished) .OrderByDescending(p => p.Date) .Take(5)) .ThenInclude(p => p.Comments) .ToList();

Q25.
How does EF Core translate a LINQ query into SQL, and what does it mean for an expression to be 'translatable'?

Mid

EF Core builds an expression tree from your LINQ query, then a provider-specific pipeline parses it, replaces parts it recognizes with SQL constructs, and generates a single SQL command; an expression is 'translatable' if the provider knows how to express it in SQL.

  • LINQ becomes an expression tree: Because IQueryable captures the query as data (not compiled delegates), EF can inspect and rewrite it.

  • The provider translates to SQL: EF maps known methods/operators (e.g. Where, string.StartsWith) to SQL equivalents (WHERE, LIKE).

  • 'Translatable' means SQL-expressible: Custom C# methods or unsupported calls have no SQL counterpart and throw an exception at query time.

  • Client evaluation: Modern EF Core only allows client evaluation on the final projection; untranslatable predicates fail instead of silently fetching all rows.

  • Fix by forcing client side explicitly: Call AsEnumerable() or ToList() to switch to in-memory LINQ when a piece genuinely can't be translated.

Q26.
What are Shadow Properties in EF Core, and what are some common use cases for them?

Mid

Shadow properties are properties that exist in the EF Core model and map to database columns but have no corresponding CLR property on the entity class; you read and write them through the change tracker rather than directly on the object.

  • Defined in the model, not the class: Configured via modelBuilder with Property<T>("Name"), and accessed through context.Entry(entity).Property("Name").

  • Common use cases:

    • Audit fields like LastModified or CreatedAt you set in SaveChanges() without polluting the domain model.

    • Foreign keys: EF often creates a shadow FK when a relationship has no explicit FK property on the class.

  • Usable in queries: Reference them in LINQ with EF.Property<T>(e, "Name").

  • Benefit: keeps persistence concerns out of your entity classes for cleaner domain models.

Q27.
Explain the concept of 'Owned Entity Types.' How do they differ from regular entities in the database schema?

Mid

Owned entity types model objects that have no identity of their own and belong entirely to an owner (value objects); by default EF Core stores their data in the same table as the owner rather than as a separate entity with its own key.

  • No independent identity: An owned type has no primary key of its own; its lifecycle is bound to the owner and it can't be queried as a standalone DbSet.

  • Schema: table splitting by default:

    • Owned properties become extra columns in the owner's table (e.g. Address yields Address_Street, Address_City).

    • You can instead map them to a separate table with ToTable(), or store a collection of owned types in their own table.

  • Configured with OwnsOne / OwnsMany: Use OwnsOne() for a single value object and OwnsMany() for a collection.

  • Always loaded with the owner: EF includes owned data automatically; no explicit Include() is needed.

  • Difference from regular entities: regular entities have their own key, table, and can be tracked/queried independently; owned types are an implementation of DDD value objects.

Q28.
What are Value Converters, and how would you use them to map a C# property to a format the database doesn't natively support?

Mid

Value Converters tell EF Core how to translate a C# property value into something the database column can store, and back again on read. They let you persist types the provider doesn't natively support (enums as strings, List<string> as JSON, value objects, etc.).

  • Two conversion functions: One converts the model value to the provider (column) value; the other converts back when materializing.

  • How to configure:

    • Use HasConversion() in OnModelCreating, or apply a ValueConverter instance for reuse.

    • Many built-ins exist (e.g. EnumToStringConverter).

  • Common uses:

    • Store an enum as a readable string column instead of an int.

    • Serialize a complex object/collection to JSON.

    • Map a DDD value object (e.g. Money) to a primitive column.

  • Caveats:

    • Converted columns can hurt query translation: filtering/ordering on the converted value may run client-side or behave unexpectedly.

    • For collections converted to JSON, supply a ValueComparer so change tracking detects mutations.

csharp

modelBuilder.Entity<Order>() .Property(o => o.Status) .HasConversion( v => v.ToString(), v => Enum.Parse<OrderStatus>(v));

Q29.
Explain the difference between 'Data Annotations' and the 'Fluent API'. Why is Fluent API generally preferred for complex models?

Mid

Data Annotations are attributes placed on entity properties to declare mapping rules inline, while the Fluent API configures the model in code through OnModelCreating. The Fluent API is preferred for complex models because it is more expressive and keeps mapping out of your domain classes.

  • Data Annotations:

    • Attributes like [Key], [Required], [MaxLength] applied directly to the model.

    • Quick and readable for simple constraints, but couple persistence concerns to the domain class.

  • Fluent API:

    • Method chains in OnModelCreating (or an IEntityTypeConfiguration<T>) describing the model.

    • Keeps entities clean POCOs with no persistence attributes.

  • Why Fluent API wins for complex models:

    • It can express things annotations can't: composite keys, complex relationships, HasConversion, split tables, indexes with filters, owned types.

    • Configuration is centralized and testable, not scattered across classes.

    • Fluent API overrides annotations when both are present, so it gives final say.

  • Common practice: mix both, simple rules via annotations, advanced mapping via Fluent API.

Q30.
How do you configure a composite primary key in EF Core?

Mid

A composite primary key (a key made of more than one column) can only be configured with the Fluent API, by passing multiple properties to HasKey(). Data Annotations cannot define one because [Key] alone doesn't support ordering across multiple properties.

  • Use HasKey with an anonymous object: List the properties in the order you want them in the key.

  • Order matters: It affects the clustered index column order and query performance.

  • No auto-generation by default: Composite key columns are typically supplied by you, not database-generated.

csharp

modelBuilder.Entity<OrderLine>() .HasKey(ol => new { ol.OrderId, ol.ProductId });

Q31.
How do you define and configure indexes, including unique and composite indexes, in EF Core?

Mid

Indexes are configured primarily with the Fluent API using HasIndex(), which you can then make unique, composite, named, or filtered. An [Index] attribute also exists for simpler cases.

  • Basic index: Call HasIndex(e => e.Property) to create a non-unique index for faster lookups.

  • Unique index: Chain IsUnique() to enforce uniqueness at the database level.

  • Composite index: Pass an anonymous object with multiple properties; column order matters for query matching.

  • Extras:

    • Name it with HasDatabaseName(), or create a filtered index with HasFilter().

    • Indexes are a database concern only: they don't appear in the C# model or affect query syntax.

csharp

modelBuilder.Entity<User>() .HasIndex(u => u.Email) .IsUnique(); modelBuilder.Entity<Person>() .HasIndex(p => new { p.LastName, p.FirstName }) .HasDatabaseName("IX_Person_Name");

Q32.
How do you configure a one-to-one relationship in EF Core and how does it differ from one-to-many?

Mid

A one-to-one relationship links one principal to at most one dependent, configured with HasOne().WithOne(). The key difference from one-to-many is that the dependent's foreign key must be unique (often the dependent shares or uniquely references the principal's key), so each side has only one related row.

  • Configuration:

    • Use HasOne(x => x.Detail).WithOne(d => d.Parent) and explicitly declare the FK with HasForeignKey<TDependent>(d => d.ParentId).

    • You must specify which entity is the dependent, since EF can't infer it as it can with one-to-many.

  • How it differs from one-to-many:

    • One-to-many: dependent FK is non-unique, so many children point to one parent, and the parent holds a collection.

    • One-to-one: dependent FK gets a unique index, so only one child per parent, and both navigations are single references.

  • Common patterns:

    • The dependent can use the principal's PK as both its PK and FK (shared primary key), making it identifying.

    • Often modeled instead as an owned type (OwnsOne) when the dependent is conceptually part of the principal.

csharp

modelBuilder.Entity<User>() .HasOne(u => u.Profile) .WithOne(p => p.User) .HasForeignKey<Profile>(p => p.UserId);

Q33.
How do you map an entity to a database view or a keyless entity type in EF Core?

Mid

Map a view or a read-only result to a keyless entity type: mark it with HasNoKey() and point it at the view with ToView() (or ToSqlQuery()), so EF treats it as a non-tracking, no-identity, read-only source.

  • Declare it as keyless:

    • Use [Keyless] attribute or modelBuilder.Entity<T>().HasNoKey() in OnModelCreating.

    • Keyless types are never tracked and have no identity resolution, so they are ideal for read-only projections.

  • Point it at the source:

    • ToView("ViewName") maps to a database view; ToSqlQuery("SELECT ...") maps to raw SQL.

    • EF will not generate migrations to create the view; you author the view yourself.

  • Querying and limitations:

    • Query it like any DbSet<T> but inserts/updates/deletes are not supported (read-only).

    • A keyless type can still have navigation properties to keyed entities, but no other entity can navigate to it.

csharp

modelBuilder.Entity<CustomerOrderTotal>(b => { b.HasNoKey(); b.ToView("vw_CustomerOrderTotals"); }); // usage var totals = await db.Set<CustomerOrderTotal>().ToListAsync();

Q34.
What is the difference between Update() and Attach()?

Mid

Both start tracking a detached entity, but Update() marks it as Modified (so EF will UPDATE every property), whereas Attach() marks it as Unchanged (so nothing is sent until you actually change something).

  • Update():

    • Sets the root to Modified; on save it issues an UPDATE of all columns (it doesn't know which actually changed).

    • Useful for disconnected scenarios where you receive a full entity (e.g. a web PUT) and want to persist it wholesale.

    • Entities with no generated key value are instead marked Added.

  • Attach():

    • Sets the root to Unchanged; nothing is persisted until you mutate a property or set state manually.

    • Ideal when you have a known-unchanged entity you just need tracked (e.g. to set a foreign key, or to delete by stub).

  • Both walk the graph: Reachable entities are tracked too; their state depends on whether they have key values.

Q35.
What is the difference between context.Add() and context.Attach()?

Mid

context.Add() marks the entity as Added so it is INSERTed on save, while context.Attach() marks it as Unchanged so it is tracked as an existing row and not persisted until modified.

  • context.Add():

    • State becomes Added; SaveChanges generates an INSERT and fills store-generated keys.

    • Use for brand-new data that doesn't yet exist in the database.

  • context.Attach():

    • State becomes Unchanged; EF assumes the row already exists and emits nothing until a property changes.

    • Use to bring an existing, known entity back under tracking (disconnected scenarios, setting FKs, stub deletes).

  • Graph behavior: Both traverse related entities; entities without key values are treated as Added, those with keys as Unchanged (for Attach).

Q36.
What is the difference between Add(), Attach(), and Update() when dealing with disconnected entities?

Mid

All three set an entity's EntityState in the change tracker, but they differ in what state they assign and what gets written: Add() marks everything as new (Added), Attach() marks it Unchanged, and Update() marks it Modified.

  • Add() sets state to Added: On SaveChanges() it issues an INSERT; the whole graph (untracked related entities) is also marked Added.

  • Attach() sets state to Unchanged:

    • No SQL is generated unless you then modify a property, which flips only that property to Modified.

    • Useful when you know nothing changed but want the entity tracked (e.g. to set a relationship).

  • Update() sets state to Modified:

    • On save it issues an UPDATE of all columns (EF can't tell which actually changed on a disconnected entity).

    • Entities with no key value are treated as Added instead.

  • Key-based decision for graphs: For Add, Attach, and Update, EF inspects each entity's key: no key value means insert, a set key means the chosen state.

Q37.
What is the difference between SaveChanges and SaveChangesAsync, and why is async querying important in EF Core?

Mid

SaveChanges() blocks the calling thread until the database round-trip completes, while SaveChangesAsync() returns a Task you await, freeing the thread during the I/O wait. Async matters because database calls are I/O-bound, and releasing the thread improves scalability under load.

  • Same work, different threading model: Both persist tracked changes in a transaction; only the wait behavior differs.

  • Why async scales: While awaiting the DB, the thread returns to the pool to serve other requests, so a web server handles more concurrent requests with fewer threads.

  • Applies to queries too: Use ToListAsync(), FirstOrDefaultAsync(), etc. for the same benefit when reading.

  • Caveats:

    • A single DbContext is not thread-safe; never run two async EF operations on the same context concurrently.

    • Async adds slight overhead, so it does not speed up a single query; it improves throughput, not latency.

Q38.
How can you update or delete an entity without first querying it from the database?

Mid

You can avoid the SELECT by either attaching a stub entity with just its key and marking it Modified/Deleted, or by using the EF Core 7+ bulk APIs ExecuteUpdate() and ExecuteDelete() which run SQL directly without loading or tracking.

  • Stub entity approach (change tracker):

    • Create an instance with only the key set, Attach() it, set state to Modified or Deleted, then SaveChanges().

    • For updates this writes all columns unless you mark only specific properties Modified.

  • Bulk approach (EF Core 7+):

    • ExecuteUpdate() / ExecuteDelete() translate to a single UPDATE/DELETE statement, bypassing change tracking entirely.

    • More efficient for set-based operations, but they do not update entities already tracked in memory.

csharp

// Stub: delete without loading var stub = new Blog { Id = 5 }; context.Blogs.Remove(stub); // attaches + marks Deleted await context.SaveChangesAsync(); // Bulk: single SQL statement, no tracking (EF Core 7+) await context.Blogs .Where(b => b.Id == 5) .ExecuteDeleteAsync();

Q39.
How does EF Core handle Many-to-Many relationships differently in modern versions (5.0+) compared to older versions?

Mid

Since EF Core 5.0, many-to-many relationships can be modeled directly with collection navigations on both sides and no explicitly defined join entity: EF creates and manages the join table automatically. Before 5.0 you had to define the join entity class yourself and map two one-to-many relationships through it.

  • Old way (pre-5.0):

    • Required an explicit join class (e.g. PostTag) with both foreign keys and navigations on each entity pointing to it.

    • Verbose: you queried and saved through the join entity.

  • New way (5.0+):

    • Just put ICollection<T> on each side; EF infers a shared join table automatically.

    • You manipulate the relationship by adding/removing objects from the collections.

  • Best of both: skip navigations: You can still customize the join table via UsingEntity() to add payload columns (e.g. a timestamp) while keeping the simple navigations.

csharp

// EF Core 5+ : no join entity needed public class Post { public List<Tag> Tags { get; set; } } public class Tag { public List<Post> Posts { get; set; } } // EF auto-creates PostTag join table. // Customize the join table when needed: modelBuilder.Entity<Post>() .HasMany(p => p.Tags) .WithMany(t => t.Posts) .UsingEntity<PostTag>();

Q40.
Explain the behavior of 'Cascade Delete' vs. 'SetNull' in EF Core. How does the framework decide which to use by default?

Mid

Both define what happens to dependent (child) rows when a principal (parent) is deleted: Cascade deletes the children too, while SetNull sets their foreign key to null and keeps them. EF chooses the default based on whether the relationship is required or optional.

  • Cascade: Deleting the principal deletes all dependents; default for required relationships (non-nullable FK), since orphans can't legally exist.

  • SetNull (ClientSetNull / SetNull): Dependents survive with a null FK; default for optional relationships (nullable FK).

  • How EF decides: Required (FK not nullable) defaults to Cascade; optional (FK nullable) defaults to ClientSetNull.

  • Client vs database behavior: ClientSetNull only nulls FKs for entities tracked in memory; SetNull pushes ON DELETE SET NULL to the database too.

  • Override explicitly: Configure with OnDelete(DeleteBehavior.Restrict) or others in OnModelCreating when the default isn't what you want.

Q41.
What are the pros and cons of using navigation properties versus just using foreign key IDs?

Mid

Navigation properties give you object-graph access (e.g. order.Customer) which is expressive and lets EF manage relationships, while raw FK ID properties are lighter and give you direct control over the key without loading the related entity. Best practice is usually to expose both.

  • Navigation properties: pros:

    • Natural object-oriented traversal and richer LINQ queries (Include(), filtering on related data).

    • EF can set relationships by assigning objects, and supports lazy/eager loading.

  • Navigation properties: cons:

    • Easy to trigger unintended queries (lazy loading, N+1).

    • Require the related entity to be loaded/attached to set the relationship.

  • FK ID properties: pros:

    • Set a relationship by assigning just the ID (e.g. order.CustomerId = 5) without loading the principal.

    • Ideal for disconnected/web scenarios and lean DTO mapping.

  • FK ID properties: cons: No direct access to related data; less expressive in code.

  • Recommended approach: Define both a navigation and its explicit FK property; you get convenience plus the ability to set relationships by key.

Q42.
How do you handle Data Seeding in EF Core, and what is the difference between Model Seeding and Manual Migrations Seeding?

Mid

EF Core seeds data either through the model (declarative, tied to migrations) or manually in your own code at startup. Model seeding is reproducible and version-controlled via migrations; manual seeding gives full flexibility but isn't tracked by the migration system.

  • Model Seeding with HasData():

    • Declared in OnModelCreating; EF generates Insert/Update/Delete operations into the migration.

    • Requires explicit primary key values and is meant for static reference data (lookups, enums).

    • Can't use dynamic values (no DateTime.Now, no related FKs resolved at runtime) and can't depend on existing DB data.

  • Manual / Migration Seeding:

    • You add custom code in your app startup or write raw SQL inside a migration with migrationBuilder.Sql().

    • Good for large datasets, conditional logic, or environment-specific data; you control idempotency yourself.

  • Difference in a sentence: Model seeding is declarative and diffed by EF into migrations; manual seeding is imperative code/SQL that EF does not manage.

csharp

modelBuilder.Entity<Role>().HasData( new Role { Id = 1, Name = "Admin" }, new Role { Id = 2, Name = "User" });

Q43.
What is the purpose of the __EFMigrationsHistory table and the Model Snapshot file?

Mid

Together they let EF Core track migration state: the __EFMigrationsHistory table records which migrations have been applied to a given database, while the model snapshot records what the model looked like after the last migration so EF can diff against it to generate the next one.

  • __EFMigrationsHistory (in the database):

    • One row per applied migration (MigrationId and ProductVersion).

    • At runtime EF compares pending migrations against this table to decide what to apply.

  • Model snapshot (ModelSnapshot.cs, in source):

    • A C# representation of the current model state, updated each time you add or remove a migration.

    • When you scaffold a new migration, EF diffs the current model against the snapshot to compute only the changes.

  • Why both matter: The snapshot answers "what does the code expect?"; the history table answers "what has the database actually received?"

Q44.
What is the purpose of the 'Model Snapshot' file in EF Core Migrations?

Mid

The model snapshot is a generated C# file that captures the complete shape of your model as of the most recent migration. EF Core diffs your current model against it to figure out exactly what changed when you scaffold the next migration.

  • What it is: A single ModelSnapshot.cs file (one per context) describing entities, keys, indexes, and relationships.

  • Why it exists:

    • Without it, EF couldn't know the previous model state and would have to regenerate the entire schema each time.

    • Adding a migration updates the snapshot; removing a migration reverts it.

  • Gotcha:

    • It must be committed to source control and kept in sync; a corrupted or out-of-date snapshot produces wrong or empty migrations.

    • Merge conflicts in the snapshot are common; resolve by re-scaffolding rather than hand-editing.

Q45.
Explain the different lifetimes for a DbContext when registered in a dependency injection container. Why is 'Scoped' usually the default?

Mid

A DbContext can be registered as Scoped, Transient, or Singleton, but Scoped (one instance per request/scope) is the natural fit because it matches the unit-of-work pattern and respects the context's non-thread-safe nature.

  • Scoped (the default):

    • One DbContext per scope (in ASP.NET Core, per HTTP request), shared by all services in that request.

    • Acts as a single unit of work: changes tracked across the request are saved together and disposed at request end.

  • Transient: A new instance every time it's requested, so services in the same request get separate change-trackers and connections (usually wasteful and confusing).

  • Singleton: One instance for the whole app: dangerous because the context isn't thread-safe and its change-tracker grows unbounded, causing concurrency bugs and memory leaks.

  • Why Scoped wins:

    • Each request is effectively single-threaded through the context, avoiding concurrency issues while keeping a clean, short-lived tracking scope.

    • AddDbContext() registers it as Scoped by default for this reason.

csharp

// Scoped by default builder.Services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(connectionString));

Q46.
Why is a DbContext not thread-safe, and what happens if you attempt to use it across multiple threads?

Mid

A DbContext holds mutable, unsynchronized state (the change tracker, the database connection, internal caches), so concurrent access corrupts that state. EF Core actively detects overlapping operations and throws rather than silently misbehaving.

  • Shared mutable state: The change tracker and identity map aren't guarded by locks; two threads mutating them race and leave entities in an inconsistent state.

  • One underlying connection/command: A single context typically uses one connection; running two queries at once collides on it.

  • What actually happens:

    • EF Core throws an InvalidOperationException: "A second operation was started on this context instance before a previous operation completed."

    • Common cause: firing multiple awaited queries without awaiting each, e.g. Task.WhenAll over the same context.

  • The fix: Await operations sequentially on one context, or use a separate context instance per parallel operation (e.g. via IDbContextFactory).

Q47.
What are Global Query Filters, and how would you use them to implement Soft Delete or Multi-tenancy?

Mid

Global query filters are LINQ predicates declared on an entity in OnModelCreating that EF Core automatically appends to every query targeting that entity. They centralize cross-cutting WHERE conditions like soft-delete and tenant isolation so you don't repeat them on each query.

  • How they work:

    • Defined with HasQueryFilter(); applied to LINQ queries, including those reached via navigation/includes.

    • Bypass per-query with IgnoreQueryFilters() when you need the unfiltered set.

  • Soft delete: Filter out rows where IsDeleted is true so "deleted" records stay in the table but vanish from normal queries.

  • Multi-tenancy:

    • Filter by a TenantId captured from the current user/request, so each tenant only sees its own rows.

    • Reference an instance field so the value is read dynamically at query time.

  • Caveat: Only one filter per entity type (combine conditions with &&), and required navigations to filtered entities can change query results unexpectedly.

csharp

modelBuilder.Entity<Post>() .HasQueryFilter(p => !p.IsDeleted && p.TenantId == _tenantId);

Q48.
What logging capabilities does EF Core provide, and how can you see the SQL it generates?

Mid

EF Core uses the standard Microsoft.Extensions.Logging framework, so it integrates with any configured logger (console, debug, Serilog, etc.) and can emit the SQL it generates, parameter values, change-tracking events, and more.

  • Built on the standard logging abstraction: In ASP.NET Core, EF Core picks up the app's ILoggerFactory automatically via DI, so SQL appears in your normal log output.

  • Quick console output for diagnostics: Use LogTo(Console.WriteLine) on the DbContextOptionsBuilder to stream SQL without configuring a full logging stack.

  • Sensitive data and detailed errors:

    • By default parameter values are redacted; enable EnableSensitiveDataLogging() to see actual values (dev only).

    • EnableDetailedErrors() surfaces richer exception detail for query/save failures.

  • Filtering by category and level: Filter on DbLoggerCategory.Database.Command to log just SQL commands, or use event IDs like RelationalEventId.CommandExecuted.

  • Other tooling: ToQueryString() returns the SQL for a single query without executing it, and interceptors (IDbCommandInterceptor) give programmatic access to commands.

csharp

optionsBuilder .LogTo(Console.WriteLine, LogLevel.Information) .EnableSensitiveDataLogging(); // dev only: shows parameter values // Inspect SQL for a single query without running it var sql = context.Users.Where(u => u.IsActive).ToQueryString();

Q49.
How does EF Core implement Optimistic Concurrency? Explain the role of a RowVersion or Concurrency Token.

Mid

EF Core implements optimistic concurrency by tracking a concurrency token: a column whose original value is included in the WHERE clause of UPDATE/DELETE. If another user changed the row first, zero rows match and EF throws a concurrency exception.

  • How the check works:

    • EF generates UPDATE ... WHERE Id = @id AND Token = @originalToken and inspects rows affected.

    • Zero rows affected means the row was modified or deleted by someone else since you read it.

  • RowVersion (recommended):

    • A byte[] property marked [Timestamp] maps to a database rowversion/timestamp column that the DB auto-increments on every change.

    • It protects the whole row without you tracking individual columns.

  • Concurrency token on a specific property: Mark a regular property with [ConcurrencyCheck] or .IsConcurrencyToken() to guard just that column (e.g. a balance or status).

  • On conflict: SaveChanges() throws DbUpdateConcurrencyException, which you catch to reload, merge, or reject the change.

csharp

public class Product { public int Id { get; set; } public decimal Price { get; set; } [Timestamp] // maps to a DB rowversion column public byte[] RowVersion { get; set; } }

Q50.
How does EF Core handle transactions by default, and when would you need to manually use IDbContextTransaction?

Mid

By default every call to SaveChanges() runs in its own implicit transaction: all the inserts/updates/deletes from that call either all commit or all roll back. You only need an explicit IDbContextTransaction when one atomic unit must span multiple SaveChanges() calls or raw commands.

  • Default behavior: A single SaveChanges() is automatically atomic, so you rarely manage transactions manually.

  • When to go manual:

    • Multiple SaveChanges() calls that must succeed or fail together.

    • Mixing EF operations with raw SQL (ExecuteSqlRaw) in one unit of work.

    • Needing a specific isolation level.

  • How to use it: Call Database.BeginTransaction(), do the work, then Commit(); a thrown exception or Rollback() undoes it (dispose rolls back if not committed).

  • With retrying strategies: Wrap the manual transaction in CreateExecutionStrategy().Execute(...) so it can be retried as a whole.

csharp

using var tx = await context.Database.BeginTransactionAsync(); try { context.Orders.Add(order); await context.SaveChangesAsync(); context.Inventory.Update(item); await context.SaveChangesAsync(); await tx.CommitAsync(); } catch { await tx.RollbackAsync(); throw; }

Q51.
Explain the difference between Optimistic and Pessimistic concurrency. Which one does EF Core support natively?

Mid

Optimistic concurrency assumes conflicts are rare and detects them at save time without locking, while pessimistic concurrency locks the data up front so others can't change it. EF Core natively supports the optimistic model.

  • Optimistic concurrency:

    • No locks held while data is read or edited; conflicts are detected at SaveChanges() via a concurrency token / RowVersion.

    • Best for web apps where read-then-write spans a stateless request and long locks would be harmful.

  • Pessimistic concurrency:

    • Acquires database locks (e.g. SELECT ... FOR UPDATE) so no one else can modify the row until you finish.

    • Prevents conflicts entirely but reduces concurrency and risks deadlocks.

  • What EF Core provides:

    • Native optimistic support through concurrency tokens, surfacing DbUpdateConcurrencyException on conflict.

    • No built-in pessimistic API; you must use raw SQL with locking hints inside an explicit transaction.

Q52.
How do Interceptors work in EF Core, and when would you use one?

Senior

Interceptors let you hook into EF Core's internal operations (commands, connections, transactions, saving changes) to observe or mutate them before/after they execute. You register an implementation of an interceptor interface and EF calls it at defined points in the pipeline.

  • They implement specific interfaces: e.g. IDbCommandInterceptor (SQL commands), ISaveChangesInterceptor (SaveChanges), IDbConnectionInterceptor, IDbTransactionInterceptor.

  • Each hook has a "-ing" and "-ed" pair:

    • e.g. ReaderExecuting runs before the query (you can inspect/alter the command) and ReaderExecuted runs after.

    • You can suppress or replace results by returning an InterceptionResult.

  • Registered per context: Via optionsBuilder.AddInterceptors(...) in OnConfiguring or DI setup.

  • When to use: Cross-cutting concerns: SQL logging/auditing, soft-delete or tenant filters, setting audit fields in SavingChanges, adding query hints, or measuring command timing.

  • Difference from events/logging: Unlike simple logging, interceptors can mutate the operation, not just observe it.

Q53.
Explain the difference between AsNoTracking() and AsNoTrackingWithIdentityResolution().

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q54.
What is the difference between identifying and non-identifying relationships in EF Core?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q55.
What is the 'Backing Field' concept in EF Core, and how does it support encapsulation in Domain-Driven Design?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q56.
How does EF Core's Change Tracker detect changes in an entity, comparing snapshot-based vs. notification-based tracking?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q57.
When would you use Compiled Queries (EF.CompileAsyncQuery), and what performance benefit do they provide?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q58.
What is 'Identity Resolution' and why is it important when tracking entities?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q59.
How do Compiled Models (introduced in EF Core 6/8) improve startup time in large applications?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q60.
Explain the difference between TPH, TPT, and TPC inheritance mapping. When would you choose one over the others?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q61.
What are the different DeleteBehavior options in EF Core and how do they map to the database?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q62.
In a production environment, why is it often recommended to use SQL scripts for migrations rather than calling context.Database.Migrate() at runtime?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q63.
What is DbContext Pooling, why would you use it, and what are the potential pitfalls regarding state?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q64.
Explain DbContext Pooling. How does it differ from Connection Pooling?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q65.
What is client vs. server evaluation, and why did EF Core 3.0+ change how it handles untranslatable LINQ expressions?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q66.
What are 'ExecuteUpdate' and 'ExecuteDelete' (Bulk Updates) and how do they differ from the standard SaveChanges workflow?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q67.
How does EF Core handle 'Batching' of statements, and how does this affect performance during bulk inserts or updates?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q68.
How does EF Core support JSON columns, and how does it translate LINQ queries against JSON properties?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q69.
What is an Execution Strategy, and how does it help with connection resiliency and retries?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q70.
How do concurrency conflicts surface in EF Core, and how do you handle a DbUpdateConcurrencyException?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.