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?
A 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
Post a Comment