EF Core interview questions for beginners

1. What is Entity Framework Core (EF Core)?

EF Core is an open-source Object-Relational Mapper (ORM) that enables .NET developers to work with databases using .NET objects. It allows you to interact with a database using strongly typed classes and LINQ queries, rather than writing raw SQL queries. EF Core supports various database providers, such as SQL Server, SQLite, PostgreSQL, MySQL, and more.

2. What are the advantages of using EF Core over traditional ADO.NET?

  • Productivity: EF Core allows you to work with databases using high-level objects, reducing the amount of boilerplate code you need to write.
  • Cross-platform: EF Core supports multiple databases and works on Windows, Linux, and macOS.
  • LINQ Support: You can query the database using LINQ, which is more type-safe and easier to maintain than raw SQL queries.
  • Code-First & Database-First: EF Core supports both approaches to model databases.
  • Change Tracking: EF Core automatically tracks changes to entities and provides automatic database updates.

3. What is the difference between Code-First, Database-First, and Model-First approaches in EF Core?

  • Code-First: You create the C# classes first, and EF Core generates the database schema based on these classes. It's mostly used in modern applications.
  • Database-First: You start with an existing database, and EF Core generates C# classes (models) from the database schema.
  • Model-First: This is similar to Code-First, but you create a conceptual model (EDMX file) first, and then generate the database and C# classes from that model. (This is mostly used in older versions of Entity Framework, not EF Core.)

4. What are DbContext and DbSet in EF Core?

  • DbContext: Represents a session with the database, including methods for querying and saving data. It is the primary class responsible for interacting with the database.
  • DbSet: Represents a collection of entities of a specific type that can be queried and saved. It is essentially a table in the database.

5. How do you create a DbContext class in EF Core?

To create a DbContext, you create a class that inherits from DbContext and defines DbSet<TEntity> properties for each entity type:

public class ApplicationDbContext : DbContext

{

    public DbSet<User> Users { get; set; }

    public DbSet<Product> Products { get; set; }

 

    // Configure the connection string in OnConfiguring or in Startup.cs

    protected override void OnConfiguring(DbContextOptionsBuilder options)

        => options.UseSqlServer("YourConnectionString");

}

6. What is the difference between Add(), AddRange(), Update(), and Remove() methods in EF Core?

  • Add(): Adds a single entity to the DbSet and marks it as Added in the change tracker.
  • AddRange(): Adds multiple entities to the DbSet in a single operation.
  • Update(): Marks the entity as modified, meaning that EF Core will assume it needs to update the database.
  • Remove(): Marks the entity as deleted and deletes it from the database upon saving changes.

7. What is Change Tracking in EF Core?

Change tracking in EF Core refers to the mechanism that tracks changes made to entities (insert, update, or delete). When you retrieve an entity from the database and modify it, EF Core tracks the changes and can automatically update the database when SaveChanges() is called.

8. What are migrations in EF Core?

Migrations in EF Core are used to manage changes to the database schema over time. You can use migrations to apply schema changes to the database and keep it in sync with your entity classes. The basic commands are:

  • Add-Migration <MigrationName>: Creates a new migration file based on changes to the model.
  • Update-Database: Applies pending migrations to the database.
  • Remove-Migration: Removes the last migration.

9. What is Lazy Loading in EF Core?

Lazy Loading is a feature that allows related entities to be automatically loaded from the database when they are accessed for the first time. In EF Core, lazy loading can be enabled by adding a navigation property and installing the Microsoft.EntityFrameworkCore.Proxies package.

Example:

public class Blog

{

    public int BlogId { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }  // Lazy Loading

}

10. What is Eager Loading in EF Core?

Eager Loading is the process of loading related data along with the main entity in a single query. You can use the Include() method to load related entities eagerly.

Example:

var blog = context.Blogs

                  .Include(b => b.Posts)

                  .ToList();

11. What is Explicit Loading in EF Core?

Explicit Loading allows you to load related data manually after the main entity has been retrieved. You use the Load() method on a navigation property to explicitly load related entities.

Example:

var blog = context.Blogs.Find(1);

context.Entry(blog).Collection(b => b.Posts).Load();

12. What is the difference between Find() and FirstOrDefault() in EF Core?

 

  • Find(): Searches the primary key for a specific entity and returns it if found. It returns null if the entity is not found.
  • FirstOrDefault(): Queries the database using LINQ and returns the first entity that matches the criteria or null if no match is found.

Example:

var user = context.Users.Find(1); // Primary Key Search

var firstUser = context.Users.FirstOrDefault(u => u.Name == "John");

13. How can you perform a raw SQL query in EF Core?

You can use the FromSqlRaw() method to execute raw SQL queries. The result must be an entity or a set of entities.

Example:

var users = context.Users.FromSqlRaw("SELECT * FROM Users WHERE Age > {0}", 18).ToList();

14. What is the purpose of the AsNoTracking() method in EF Core?

The AsNoTracking() method is used to disable change tracking for the returned entities. This is useful when you only need to read data and do not plan on making changes to it, improving performance by avoiding the overhead of tracking changes.

Example:

var users = context.Users.AsNoTracking().ToList();

15. How can you prevent EF Core from creating a database on DbContext initialization?

To prevent EF Core from automatically creating the database, you can use the EnsureCreated() method or disable automatic migration in your configuration.

Example:

public class ApplicationDbContext : DbContext

{

    public DbSet<User> Users { get; set; }

 

    protected override void OnConfiguring(DbContextOptionsBuilder options)

        => options.UseSqlServer("YourConnectionString")

                  .EnableSensitiveDataLogging(false)

                  .DisableChangeTracking();

}

 

16. What is the difference between SaveChanges() and SaveChangesAsync() in EF Core?

 

  • SaveChanges(): This method is synchronous and saves all changes made in the context to the database. It blocks the thread until the operation is complete.
  • SaveChangesAsync(): This method is asynchronous and returns a Task. It performs the save operation asynchronously, which is non-blocking and allows for better performance, especially in web applications.

Example:

await context.SaveChangesAsync(); // Asynchronous operation

context.SaveChanges(); // Synchronous operation

17. What are Shadow Properties in EF Core?

Shadow properties are properties that are not defined in the entity class but exist in the database. EF Core automatically creates and tracks these properties without adding them to the model class.

Example:

public class Blog

{

    public int BlogId { get; set; }

    public string Name { get; set; }

    // No explicit definition for CreatedDate in class

}

 

// Shadow property for CreatedDate

modelBuilder.Entity<Blog>().Property<DateTime>("CreatedDate");

18. What is the purpose of the HasData() method in EF Core?

The HasData() method is used in EF Core to seed the database with initial data. It is commonly used in migrations to insert predefined records into the database after creating or updating the schema.

Example:

modelBuilder.Entity<User>().HasData(

    new User { UserId = 1, Name = "John Doe", Age = 30 },

    new User { UserId = 2, Name = "Jane Doe", Age = 25 }

);

19. How can you configure a many-to-many relationship in EF Core?

In EF Core 5.0 and later, many-to-many relationships can be configured without requiring a join entity. EF Core will automatically create the join table for you.

Example:

public class Student

{

    public int StudentId { get; set; }

    public string Name { get; set; }

    public ICollection<Course> Courses { get; set; }

}

 

public class Course

{

    public int CourseId { get; set; }

    public string Title { get; set; }

    public ICollection<Student> Students { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<Student>()

        .HasMany(s => s.Courses)

        .WithMany(c => c.Students)

        .UsingEntity<Dictionary<string, object>>(

            "StudentCourse");

}

20. What is the ModelBuilder in EF Core?

The ModelBuilder is a class in EF Core used to configure the schema of the database using the Fluent API. It is typically used in the OnModelCreating() method of DbContext to configure relationships, keys, constraints, indexes, etc.

Example:

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasKey(u => u.UserId);

    modelBuilder.Entity<User>()

        .Property(u => u.Name)

        .IsRequired();

}

21. What is a ValueConverter in EF Core?

A ValueConverter in EF Core is used to convert the data between its representation in the application and its representation in the database. It is useful for tasks like encrypting data or storing enums as integers.

Example:

modelBuilder.Entity<User>()

    .Property(u => u.Status)

    .HasConversion(

        v => v.ToString(),

        v => (Status)Enum.Parse(typeof(Status), v));

22. What is a Composite Key in EF Core?

A composite key is a key composed of multiple properties. EF Core allows you to define composite keys using the HasKey() method in the OnModelCreating() method.

Example:

public class OrderItem

{

    public int OrderId { get; set; }

    public int ProductId { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<OrderItem>()

        .HasKey(oi => new { oi.OrderId, oi.ProductId });

}

23. How do you handle concurrency conflicts in EF Core?

EF Core provides two types of concurrency control:

  • Optimistic Concurrency: In this approach, a column in the database (usually a timestamp or version column) is used to track if a record has been modified since it was last read. When saving, EF Core checks if the version has changed. If so, it throws a concurrency exception.
  • Pessimistic Concurrency: You can lock the data when reading it to prevent others from modifying it until the transaction completes. This is more database-dependent and not directly supported by EF Core.

Example of handling optimistic concurrency:

public class Product

{

    public int ProductId { get; set; }

    public string Name { get; set; }

    public int Quantity { get; set; }

    public byte[] RowVersion { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<Product>()

        .Property(p => p.RowVersion)

        .IsRowVersion();

}

24. What are the differences between IQueryable and IEnumerable in EF Core?

  • IQueryable: Represents a query that has not been executed yet, and it can be further composed. It is usually used with EF Core to build SQL queries that are sent to the database.
  • IEnumerable: Represents a collection of data that has been loaded into memory, typically returned from a query that has already been executed.

Example:

IQueryable<User> usersQuery = context.Users.Where(u => u.Age > 30);

IEnumerable<User> usersList = usersQuery.ToList();  // Executes the query

25. What is the difference between DbContext.SaveChanges() and DbContext.Entry().State in EF Core?

  • SaveChanges(): This method is used to persist changes to the database for all tracked entities.
  • Entry().State: This is used to manually change the state of an entity (e.g., Added, Modified, Deleted, Unchanged). It is useful when you want to explicitly set the state of an entity without performing operations directly on the entity.

Example:

var user = context.Users.Find(1);

context.Entry(user).State = EntityState.Modified;

context.SaveChanges();

26. How can you configure indexes in EF Core?

In EF Core, indexes can be configured using the HasIndex() method in the OnModelCreating() method.

Example:

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasIndex(u => u.Email)

        .IsUnique();

}

27. What is the role of Configure() method in EF Core?

The Configure() method is used to configure the entity classes using the Fluent API. It allows you to define properties, relationships, keys, indexes, and more. The Configure() method is often implemented in a separate class to keep your codebase clean.

Example:

public class UserConfiguration : IEntityTypeConfiguration<User>

{

    public void Configure(EntityTypeBuilder<User> builder)

    {

        builder.HasKey(u => u.UserId);

        builder.Property(u => u.Name).IsRequired();

    }

}

This class would then be applied in the OnModelCreating() method:

modelBuilder.ApplyConfiguration(new UserConfiguration());

 

 

28. What are the different ways to configure relationships in EF Core?

 

 

In EF Core, relationships between entities can be configured in three primary ways:

·       Fluent API: The most commonly used approach for configuring relationships.

·       Data Annotations: Simple annotations directly in the model class.

·       Convention-based configuration: EF Core automatically detects relationships based on class names and property names (though it’s less flexible than the other approaches).

 

 

Example of configuring relationships using Fluent API:

 

// One-to-many

modelBuilder.Entity<Order>()

    .HasOne(o => o.Customer)

    .WithMany(c => c.Orders)

    .HasForeignKey(o => o.CustomerId);

 

// Many-to-many (EF Core 5.0 and later)

modelBuilder.Entity<Student>()

    .HasMany(s => s.Courses)

    .WithMany(c => c.Students)

    .UsingEntity<Dictionary<string, object>>("StudentCourse");

 

29. What are the Keyless entities in EF Core?

Keyless entities in EF Core are classes that do not have a primary key. They are commonly used for views or stored procedures where you don’t need an identity or key column.

 

Example:

 

public class TempData

{

    public string Name { get; set; }

    public int Age { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<TempData>().HasNoKey();

}

 

30. What is DbContextOptions in EF Core?

DbContextOptions contains the configuration information for a DbContext instance, such as the database connection string, database provider (e.g., SQL Server, SQLite), and other configuration settings. It is passed to the DbContext constructor to configure how EF Core will connect to and interact with the database.

Example:

public class ApplicationDbContext : DbContext

{

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)

        : base(options) { }

}

 

31. How do you handle many-to-many relationships in EF Core before version 5?

 

 

In versions prior to EF Core 5.0, you had to explicitly create an entity class for the join table to represent many-to-many relationships.

Example:

public class StudentCourse

{

    public int StudentId { get; set; }

    public Student Student { get; set; }

    public int CourseId { get; set; }

    public Course Course { get; set; }

}

 

modelBuilder.Entity<StudentCourse>()

    .HasKey(sc => new { sc.StudentId, sc.CourseId });

 

modelBuilder.Entity<StudentCourse>()

    .HasOne(sc => sc.Student)

    .WithMany(s => s.StudentCourses)

    .HasForeignKey(sc => sc.StudentId);

 

modelBuilder.Entity<StudentCourse>()

    .HasOne(sc => sc.Course)

    .WithMany(c => c.StudentCourses)

    .HasForeignKey(sc => sc.CourseId);

 

32. What are Owned Entities in EF Core?

An Owned Entity is an entity that doesn’t have its own identity and is fully dependent on its parent entity. It is typically used for embedding related data as part of the parent entity, such as a complex type or a value object.

 

Example:

 

public class Address

{

    public string Street { get; set; }

    public string City { get; set; }

}

 

public class Customer

{

    public int CustomerId { get; set; }

    public string Name { get; set; }

    public Address Address { get; set; }  // Owned Entity

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<Customer>()

        .OwnsOne(c => c.Address);

}

 

33. What is Seed Data and how is it configured in EF Core?

Seed data is used to pre-populate the database with initial or default data. In EF Core, it can be added using the HasData() method in the OnModelCreating method.

Example:

modelBuilder.Entity<User>().HasData(

    new User { UserId = 1, Name = "John Doe", Age = 30 },

    new User { UserId = 2, Name = "Jane Doe", Age = 25 }

);

 

The data will be inserted into the database after a migration is applied.

 

34. How do you handle soft deletes in EF Core?

Soft delete means marking an entity as deleted without physically removing it from the database. EF Core does not have built-in support for soft deletes, but you can implement it by adding a flag (e.g., IsDeleted) to the entity and filtering out soft-deleted entities in your queries.

Example:

public class User

{

    public int UserId { get; set; }

    public string Name { get; set; }

    public bool IsDeleted { get; set; }

}

 

// Apply a global query filter to exclude deleted entities

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasQueryFilter(u => !u.IsDeleted);

}

 

35. What is the difference between IQueryable and IEnumerable in EF Core?

·       IQueryable: This is used to represent a query that can be further modified. It enables deferred execution and works with a database provider to translate LINQ queries into SQL and send them to the database.

 

·       IEnumerable: Represents a collection of objects in memory. It executes immediately and is typically used when the result set is already loaded into memory.

Example:

IQueryable<User> query = context.Users.Where(u => u.Name.StartsWith("A"));

IEnumerable<User> users = query.ToList();  // Executes the query and loads data into memory

 

36. What are Table Splitting and Shared Type Entities in EF Core?

·       Table Splitting: When two or more entities share a single table in the database. This can help with performance and schema normalization, as they can share the same columns but represent different objects.

·       Shared Type Entities: These are entities that don’t have their own table but are part of a shared schema.

Example of Table Splitting:

public class User

{

    public int UserId { get; set; }

    public string Name { get; set; }

}

 

public class UserDetails

{

    public int UserId { get; set; }

    public string Address { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .ToTable("Users")

        .HasOne(u => u.UserDetails)

        .WithOne()

        .HasForeignKey<UserDetails>(ud => ud.UserId);

}

 

37. What is Cascade Delete in EF Core and how is it configured?

Cascade delete is a rule in which the deletion of a parent entity automatically triggers the deletion of related child entities. In EF Core, cascade delete is configured using the Fluent API with OnDelete() method.

 

Example:

modelBuilder.Entity<Order>()

    .HasOne(o => o.Customer)

    .WithMany(c => c.Orders)

    .OnDelete(DeleteBehavior.Cascade); // Cascade delete

 

38. How can you handle database transactions in EF Core?

EF Core supports handling transactions using DbContext.Database.BeginTransaction(), Commit(), and Rollback() methods. Transactions allow you to group multiple operations into a single atomic unit, ensuring that all operations succeed or fail together.

Example:

using (var transaction = context.Database.BeginTransaction())

{

    try

    {

        // Perform some database operations

        context.SaveChanges();

       

        // Commit transaction

        transaction.Commit();

    }

    catch (Exception)

    {

        // Rollback transaction in case of error

        transaction.Rollback();

    }

}

 

39. What are Computed Columns in EF Core?

Computed columns are columns whose values are derived from other columns in the same table, and their values are automatically calculated by the database. In EF Core, you can configure computed columns using the Fluent API.

 

Example:

 

modelBuilder.Entity<Product>()

    .Property(p => p.TotalPrice)

    .HasComputedColumnSql("[Quantity] * [Price]");

 

40. How can you configure the database provider in EF Core?

In EF Core, the database provider is configured during the DbContext setup, typically in the OnConfiguring() method or in Startup.cs for ASP.NET Core applications.

Example of configuring SQL Server:

public class ApplicationDbContext : DbContext

{

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)

        : base(options) { }

 

    protected override void OnConfiguring(DbContextOptionsBuilder options)

        => options.UseSqlServer("ConnectionStringHere");

}

 

41. What are Database Migrations in EF Core and why are they important?

Database migrations in EF Core are used to apply schema changes (e.g., creating tables, adding columns) to the database in a controlled and versioned manner. They are important for maintaining synchronization between the code and the database schema, especially in agile development where the database schema evolves over time.

To create and apply migrations, the following commands are typically used:

·       Add-Migration MigrationName: Creates a new migration file.

·       Update-Database: Applies pending migrations to the database.

Example:

dotnet ef migrations add InitialCreate

dotnet ef database update

 

42. What is the DbSet<T> in EF Core?

DbSet<T> represents a collection of entities of type T in the context of EF Core. It is used to query and save instances of the given entity type in the database.

Example:

public DbSet<User> Users { get; set; }

 

The DbSet<T> allows for LINQ queries, CRUD operations, and more, for the specific entity.

 

43. How does EF Core handle lazy loading?

Lazy loading in EF Core allows related entities to be automatically loaded from the database when accessed for the first time. EF Core requires navigation properties to be marked as virtual for lazy loading to work, and you must enable it explicitly by installing the Microsoft.EntityFrameworkCore.Proxies package and configuring it in the DbContext.

Example:

dotnet add package Microsoft.EntityFrameworkCore.Proxies

In DbContext:

public class ApplicationDbContext : DbContext

{

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

 

    public DbSet<User> Users { get; set; }

 

    protected override void OnConfiguring(DbContextOptionsBuilder options)

    {

        options.UseLazyLoadingProxies();

    }

}

Example of lazy loading in action:

var user = context.Users.First();

var orders = user.Orders; // Lazy load related orders

 

44. What are Eager Loading and Explicit Loading in EF Core?

·       Eager Loading: This technique loads related entities as part of the initial query, reducing the number of database queries. It is achieved using the Include() method.

Example:

var usersWithOrders = context.Users

    .Include(u => u.Orders)

    .ToList();

·       Explicit Loading: This allows loading related entities after the initial query has been executed using the Load() method.

Example:

var user = context.Users.First();

context.Entry(user).Collection(u => u.Orders).Load();

 

45. What is the purpose of Database-First approach in EF Core?

The Database-First approach is used when you have an existing database, and you want to generate the entity models based on the schema of that database. EF Core allows you to reverse engineer the database into code using the Scaffold-DbContext command.

Example:

dotnet ef dbcontext scaffold "Server=localhost;Database=MyDatabase;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --output-dir Models

 

This command generates entity classes and a DbContext based on the database schema.

 

46. How do you configure a One-to-One relationship in EF Core?

A One-to-One relationship can be configured in EF Core using the HasOne() and WithOne() methods in the Fluent API.

Example:

public class User

{

    public int UserId { get; set; }

    public string Name { get; set; }

    public Profile Profile { get; set; }

}

 

public class Profile

{

    public int ProfileId { get; set; }

    public string Bio { get; set; }

    public int UserId { get; set; }

    public User User { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasOne(u => u.Profile)

        .WithOne(p => p.User)

        .HasForeignKey<Profile>(p => p.UserId);

}

 

47. What is Concurrency Control in EF Core?

Concurrency control is a mechanism used to handle cases where multiple users or processes try to modify the same data simultaneously. EF Core supports two main types of concurrency control:

·       Optimistic Concurrency: This is used when conflicts are rare. EF Core can detect if two users try to modify the same entity by comparing a version number or timestamp column.

·       Pessimistic Concurrency: This is typically handled manually, and it locks data at the database level to prevent other users from accessing it.

Example of Optimistic Concurrency using a RowVersion:

public class Product

{

    public int ProductId { get; set; }

    public string Name { get; set; }

    public byte[] RowVersion { get; set; }  // For concurrency control

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<Product>()

        .Property(p => p.RowVersion)

        .IsRowVersion();  // Mark the RowVersion as a concurrency token

}

 

48. What are Global Query Filters in EF Core?

 

 

Global query filters are filters that are automatically applied to all queries on a particular entity. They are commonly used for soft deletes or multi-tenancy scenarios where you want to filter out data globally without applying the filter manually to each query.

Example:

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasQueryFilter(u => !u.IsDeleted);  // Automatically exclude deleted users

}

 

49. What is the Tracking behavior in EF Core and how do you disable it?

EF Core uses tracking by default, meaning it tracks the state of entities (e.g., added, modified, deleted). This allows changes to be detected and saved to the database. However, in certain scenarios, you may want to disable tracking (e.g., when performing read-only queries) for better performance.

Example of disabling tracking:

var users = context.Users.AsNoTracking().ToList();  // No tracking for read-only queries

 

50. How do you configure a Unique Index in EF Core?

In EF Core, you can configure a unique index using the HasIndex() method and the IsUnique() method to ensure that a specific column or combination of columns has unique values.

Example:

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasIndex(u => u.Email)

        .IsUnique();

}

 

51. What is Database Seeding in EF Core and how is it done?

Database seeding is the process of populating the database with initial data. EF Core allows you to define seed data using the HasData() method in the OnModelCreating() method. Seeding is typically done during the migration process.

Example:

modelBuilder.Entity<User>().HasData(

    new User { UserId = 1, Name = "John Doe", Age = 30 },

    new User { UserId = 2, Name = "Jane Doe", Age = 25 }

);

 

52. What is Database Initialization in EF Core and how does it work?

Database initialization in EF Core refers to the process of setting up the database schema using migrations or creating a new database if it doesn’t exist. It can be done using commands like Update-Database or programmatically using EnsureCreated() or Migrate().

Example:

public static void Initialize(IServiceProvider serviceProvider, ApplicationDbContext context)

{

    context.Database.Migrate();  // Apply migrations to the database

}

 

 

53. What is the difference between DbContext.SaveChanges() and DbContext.SaveChangesAsync()?

·       SaveChanges() is a synchronous method that saves changes to the database and returns the number of affected rows.

·       SaveChangesAsync() is the asynchronous counterpart, which doesn't block the thread while saving changes. It is ideal for I/O-bound operations in web applications, helping improve scalability and responsiveness.

Example:

// Synchronous

context.SaveChanges();

 

// Asynchronous

await context.SaveChangesAsync();

 

54. What is DbContext in EF Core?

DbContext is the primary class responsible for interacting with the database. It represents a session with the database and allows querying and saving data. It is the bridge between the domain classes and the database.

Example:

public class ApplicationDbContext : DbContext

{

    public DbSet<User> Users { get; set; }

 

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)

        : base(options) { }

}

 

55. How can you implement a custom primary key in EF Core?

You can implement a custom primary key by using the HasKey() method in the Fluent API. This allows you to specify composite keys or custom key properties other than the default Id or ClassNameId.

 

Example of a composite key:

modelBuilder.Entity<OrderDetail>()

    .HasKey(od => new { od.OrderId, od.ProductId });

Example of a custom key:

public class User

{

    public string CustomKey { get; set; } // Custom primary key

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasKey(u => u.CustomKey);

}

 

56. What are Navigation Properties in EF Core?

Navigation properties in EF Core represent relationships between entities. They allow you to navigate from one entity to related entities. They can be either reference navigation properties (for one-to-one or many-to-one relationships) or collection navigation properties (for one-to-many or many-to-many relationships).

Example:

public class User

{

    public int UserId { get; set; }

    public string Name { get; set; }

    public ICollection<Order> Orders { get; set; }  // Collection navigation property

}

 

57. What is Fluent API in EF Core and how is it different from Data Annotations?

The Fluent API is used to configure the model classes in a more flexible and granular way using C# code. It is defined inside the OnModelCreating() method of the DbContext. In contrast, Data Annotations are attributes applied directly to the model class properties. Fluent API provides more advanced configuration options and is preferred for complex configurations.

Example of Fluent API:

modelBuilder.Entity<User>()

    .HasIndex(u => u.Email)

    .IsUnique();

Example of Data Annotations:

public class User

{

    [Key]

    public int UserId { get; set; }

 

    [Required]

    public string Name { get; set; }

}

 

58. What is the role of Transaction in EF Core?

transaction in EF Core ensures that a series of database operations are executed as a single unit of work. If one operation fails, all operations can be rolled back to maintain data integrity.

Example:

using (var transaction = context.Database.BeginTransaction())

{

    try

    {

        context.SaveChanges();

        transaction.Commit(); // Commit if everything is successful

    }

    catch (Exception)

    {

        transaction.Rollback(); // Rollback if something fails

    }

}

 

59. How does EF Core handle lazy loading with proxies?

EF Core supports lazy loading via dynamic proxy classes. These proxies are created at runtime and are used to load related entities when a navigation property is accessed for the first time. For lazy loading to work, you need to install the Microsoft.EntityFrameworkCore.Proxies package and enable it in the DbContext.

Example:

 

dotnet add package Microsoft.EntityFrameworkCore.Proxies

Enable in DbContext:

public class ApplicationDbContext : DbContext

{

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)

        : base(options) { }

 

    public DbSet<User> Users { get; set; }

 

    protected override void OnConfiguring(DbContextOptionsBuilder options)

    {

        options.UseLazyLoadingProxies();

    }

}

Example of lazy loading:

var user = context.Users.First();

var orders = user.Orders;  // Lazy load orders

 

60. What is the IsRequired() method in EF Core?

The IsRequired() method is used to mark a property as required in EF Core. It ensures that the property cannot have a null value in the database. It is commonly used to enforce business rules for mandatory fields.

Example:

modelBuilder.Entity<User>()

    .Property(u => u.Name)

    .IsRequired();  // Name must not be null

 

61. How do you configure cascading delete behavior in EF Core?

In EF Core, cascade delete is configured using the OnDelete() method in the Fluent API. This defines how related entities should be affected when a parent entity is deleted. The most common options are:

·       DeleteBehavior.Cascade: Delete related entities when the parent is deleted.

·       DeleteBehavior.Restrict: Prevent deletion of the parent if there are related entities.

·       DeleteBehavior.SetNull: Set related entities' foreign key to null on deletion.

Example:

modelBuilder.Entity<Order>()

    .HasOne(o => o.Customer)

    .WithMany(c => c.Orders)

    .OnDelete(DeleteBehavior.Cascade);  // Cascade delete on Order

 

62. What are Shadow Properties in EF Core?

Shadow properties are properties that are defined in the model but do not exist in the entity class. They are used for things like tracking metadata, such as timestamps or version numbers, without adding a physical property to the class.

Example:

modelBuilder.Entity<User>()

    .Property<DateTime>("LastModified");  // Shadow property for last modified date

 

Shadow properties are often useful for concurrency control, auditing, or versioning without modifying the entity class.

 

63. What is the IQueryable and IEnumerable difference in EF Core?

·       IQueryable: Represents a query that can be further composed and translated into SQL by the EF Core provider. It is typically used to create queries that are executed on the database.

·       IEnumerable: Represents a collection of objects that are in memory and can be enumerated. When you call ToList() or ToArray(), the query is executed, and the result is loaded into memory.

Example:

IQueryable<User> query = context.Users.Where(u => u.Age > 25);  // IQueryable (deferred execution)

 

var users = query.ToList();  // Executes the query and converts to IEnumerable

 

64. How do you prevent circular references in EF Core?

Circular references can occur when entities have navigation properties pointing to each other, creating an infinite loop during serialization. You can prevent circular references in EF Core by using attributes like [JsonIgnore] or configuring the relationship with .OnDelete(DeleteBehavior.Restrict) to prevent navigation loops.

 

Example:

public class User

{

    public int UserId { get; set; }

    public string Name { get; set; }

 

    [JsonIgnore]

    public ICollection<Order> Orders { get; set; }  // Prevent circular reference

}

Alternatively, you can configure the relationship in OnModelCreating:

modelBuilder.Entity<User>()

    .HasMany(u => u.Orders)

    .WithOne(o => o.User)

    .OnDelete(DeleteBehavior.Restrict);  // Prevent cascading delete and circular reference

 

65. How do you handle composite keys in EF Core?

Composite keys are defined by multiple properties, and they can be configured using the HasKey() method in the Fluent API.

Example:

public class OrderDetail

{

    public int OrderId { get; set; }

    public int ProductId { get; set; }

    public int Quantity { get; set; }

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<OrderDetail>()

        .HasKey(od => new { od.OrderId, od.ProductId });  // Composite key

}

 

 

66. What is the difference between Add, Attach, and Update in EF Core?

·       Add: Used to add a new entity to the context. If the entity has an identifier (primary key), it assumes it's a new entity and adds it to the Added state.

·       Attach: Attaches an entity to the context without changing its state. It’s used for entities that already exist in the database, and you don't want to modify them.

·       Update: Marks an entity as modified and tells EF Core to update the entity in the database, even if it was previously unchanged.

Example:

var user = new User { UserId = 1, Name = "John" };

context.Users.Add(user);  // Adds a new entity

 

context.Users.Attach(user);  // Attaches an existing entity without modifying it

 

user.Name = "Updated John";

context.Users.Update(user);  // Marks entity as modified

 

67. What is DbContextOptions in EF Core?

DbContextOptions is a configuration object used to configure the DbContext class. It typically contains database connection strings and other settings related to how EF Core should interact with the database, such as specifying the database provider (SQL Server, SQLite, etc.).

Example:

var options = new DbContextOptionsBuilder<ApplicationDbContext>()

    .UseSqlServer("Your_Connection_String")

    .Options;

 

var context = new ApplicationDbContext(options);

 

68. What is the use of the ValueGeneratedOnAdd() method in EF Core?

ValueGeneratedOnAdd() is used to specify that a property should be automatically generated by the database when a new entity is inserted. It is commonly used with auto-incrementing primary keys.

Example:

modelBuilder.Entity<User>()

    .Property(u => u.UserId)

    .ValueGeneratedOnAdd();  // Auto-generated value for UserId

 

69. How can you perform bulk inserts or updates in EF Core?

EF Core does not provide built-in support for bulk inserts/updates, but you can achieve bulk operations using third-party libraries such as EFCore.BulkExtensions or by executing raw SQL queries.

Example using a third-party library:

context.BulkInsert(users);  // Bulk insert users into the database

Alternatively, you can use raw SQL queries for large-scale updates:

context.Database.ExecuteSqlRaw("UPDATE Users SET Age = 30 WHERE Age > 25");

 

70. What is AsNoTracking() in EF Core and when should it be used?

AsNoTracking() is a method that tells EF Core not to track the state of entities retrieved in a query. It improves performance for read-only operations by preventing EF Core from maintaining the entities in the change tracker.

Example:

var users = context.Users.AsNoTracking().ToList();  // Read-only query, no tracking

It should be used for scenarios where the data is not going to be modified, such as in data retrieval scenarios where performance is critical.

 

71. What is Database First vs Code First approach in EF Core?

·       Database First: The database schema is already created, and EF Core is used to generate the model classes (DbContext and entities) based on the existing database schema.

·       Code First: The model classes are created first, and EF Core generates the database schema based on these classes.

You can use Scaffold-DbContext for Database First, and for Code First, you can create models and use migrations to generate the database.

 

72. What is Cascading behavior and how do you configure it in EF Core?

Cascading behavior determines how related entities are affected when the parent entity is deleted. EF Core supports several cascading options, including:

·       DeleteBehavior.Cascade: Delete related entities when the parent is deleted. 

·       DeleteBehavior.Restrict: Prevent deletion if there are related entities.

·       DeleteBehavior.SetNull: Set related entities' foreign keys to null.

Example:

modelBuilder.Entity<Order>()

    .HasOne(o => o.Customer)

    .WithMany(c => c.Orders)

    .OnDelete(DeleteBehavior.Cascade);  // Cascade delete

 

73. How do you implement a Many-to-Many relationship in EF Core?

EF Core introduced direct support for Many-to-Many relationships starting from version 5.0. To define a many-to-many relationship, you can use two navigation properties that connect two entities, and EF Core automatically creates the junction table.

Example:

public class Student

{

    public int StudentId { get; set; }

    public string Name { get; set; }

    public ICollection<Course> Courses { get; set; }

}

 

public class Course

{

    public int CourseId { get; set; }

    public string Title { get; set; }

    public ICollection<Student> Students { get; set; }

}

 

// In OnModelCreating

modelBuilder.Entity<Student>()

    .HasMany(s => s.Courses)

    .WithMany(c => c.Students);

 

74. How does EF Core handle soft deletes?

EF Core does not have built-in support for soft deletes, but you can implement it by adding a boolean property (e.g., IsDeleted) to your entity and using a global query filter to exclude the soft-deleted records in all queries.

Example:

public class User

{

    public int UserId { get; set; }

    public string Name { get; set; }

    public bool IsDeleted { get; set; }  // Soft delete flag

}

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

    modelBuilder.Entity<User>()

        .HasQueryFilter(u => !u.IsDeleted);  // Exclude soft-deleted records by default

}

 

To mark an entity as deleted:

var user = context.Users.Find(1);

user.IsDeleted = true;

context.SaveChanges();

 

75. What are Entity Splitting and Table Splitting in EF Core?

·       Entity Splitting: This is when a single entity maps to multiple tables. In EF Core, this is achieved by configuring the entity to map to more than one table in the OnModelCreating method.

Example:

modelBuilder.Entity<User>()

    .ToTable("UsersTable")

    .Property(u => u.Name)

    .HasColumnName("UserName");

 

modelBuilder.Entity<User>()

    .ToTable("UsersExtraTable")

    .Property(u => u.Age)

    .HasColumnName("UserAge");

·       Table Splitting: This is when multiple entities map to a single table. This approach is used for performance optimization when entities have a large number of properties, but only a few properties are queried at a time.

Example:

modelBuilder.Entity<User>()

    .ToTable("UserDetails")

    .Property(u => u.Name)

    .HasColumnName("UserName");

 

modelBuilder.Entity<Profile>()

    .ToTable("UserDetails")

    .Property(p => p.Address)

    .HasColumnName("UserAddress");

 

76. What is Client-side evaluation in EF Core and how can you avoid it?

Client-side evaluation happens when EF Core attempts to execute part of a LINQ query in memory instead of in the database. This can be inefficient, especially with large datasets, as it can result in pulling large amounts of data into memory.

Example:

var users = context.Users

    .Where(u => u.Name.Contains("John"))

    .OrderBy(u => u.Age)

    .ToList();  // Potential client-side evaluation

You can avoid client-side evaluation by ensuring that the operations (like Contains) are executable by the database provider. You should avoid performing operations that can’t be translated into SQL on the client side.

 

77. What is Raw SQL Query in EF Core and when should it be used?

EF Core allows executing raw SQL queries for scenarios where LINQ might not be sufficient or when performance is a concern. You can use FromSqlRaw() or ExecuteSqlRaw() to run SQL queries directly.

Example:

var users = context.Users

    .FromSqlRaw("SELECT * FROM Users WHERE Age > {0}", 30)

    .ToList();

You should use raw SQL when necessary, such as for complex queries, performance optimization, or database-specific functionality that EF Core cannot handle natively.

 

Comments

Popular posts from this blog

Multiline to singleline IN C# - CODING

EF Core interview questions for experienced