0% found this document useful (0 votes)
2 views

Unit-2

Entity Framework Core (EF Core) is a lightweight, open-source ORM for .NET applications that simplifies database interactions by allowing developers to work with data as objects. It supports various database providers, is cross-platform, and includes features like asynchronous operations and change tracking through the DbContext class. EF Core also facilitates CRUD operations, manages entity states, and supports relationships between entities, making it a powerful tool for data-driven applications.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Unit-2

Entity Framework Core (EF Core) is a lightweight, open-source ORM for .NET applications that simplifies database interactions by allowing developers to work with data as objects. It supports various database providers, is cross-platform, and includes features like asynchronous operations and change tracking through the DbContext class. EF Core also facilitates CRUD operations, manages entity states, and supports relationships between entities, making it a powerful tool for data-driven applications.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Unit 2: Entity Framework Core

*Introduction To Entity Framework Core


Entity Framework Core (EF Core) is an open-source, lightweight, extensible, and cross-platform version
of Microsoft’s popular Entity Framework data access technology.

It is designed to work with .NET Core and .NET Framework applications and provides an Object-
Relational Mapper (ORM) that enables .NET developers to work with a database using .NET objects.

It eliminates most of the data-access code that developers usually need to write.

What is ORM?

ORM stands for Object-Relational Mapping, a programming technique that allows developers to convert
data between incompatible systems, specifically between Object-Oriented Programming Languages (such
as C#, Java, etc.) and Relational Databases (such as SQL Server, MySQL, Oracle, etc.).

• ORM allows developers to work with data in terms of objects rather than tables and columns. That
means ORM automatically creates classes based on database tables, and vice versa is also true.
• It can also generate the necessary SQL to create the database based on the classes.
• As developers, we mainly work with data-driven applications, and the ORM Framework can
generate the necessary SQL (to perform the database CRUD operation) that the underlying database
can understand.
• It takes responsibility for opening the connection, executing the command, handling the
transaction to ensure data integrity, closing the connection, etc. So, in simple words, we can say
that the ORM Framework eliminates the need for most of the data access code we generally write.

Why Do We Need to Use an ORM Framework?

Let’s understand why we need to use the ORM Framework with an example. Suppose we want to develop
an application to manage the students of a college. To do this, we may need to create classes such as Student,
Department, Address, etc. Technically, we call these classes Domain classes or business objects.

Without using an ORM Framework like Entity Framework or EF Core, we have to write lots of data access
code to perform the CRUD operations, i.e., store and retrieve the Student, Department, and Address data
from the underlying database tables.

For example, to perform CRUD operations, i.e., read, insert, update, or delete from a database table, we
generally need to write the required SQL statements, which the underlying database should understand.
Again, when we want to read the data from the database into our application, we also have to write some
custom logic to map the data to our model classes like Student, Department, Address, etc. This is a common
task that we do in almost every application.

An ORM Framework like Entity Framework or EF Core can do all of the above for us and saves a lot of
time if we provide the required information to the ORM Framework. The ORM Framework sits between our
application code and the Database. It eliminates the need for most custom data-access codes we usually
write without an ORM. For a better understanding, please have a look at the following diagram:
• Cross-Platform: EF Core works on various platforms, including Windows, macOS, and
Linux.
• Extensible: EF Core is highly customizable and extensible, allowing developers to use
custom conventions, third-party plugins, and additional database providers.
• Performance: EF Core has been optimized for performance, making it suitable for small,
medium, and large-scale applications.
• Integration: EF Core integrates easily with .NET Core, making it the first choice for data
access in .NET applications.
• Flexibility: EF Core supports various database providers, which allows it to work with
different database systems.
• Modern Features: EF Core includes features like asynchronous operations, better support
for LINQ queries, and improved support for complex types and relationships.

*DbContext class
In Entity Framework Core, the DbContext class is a central part of the framework.

It represents a session with the database and is used to interact with the database through querying,
saving, and managing data.

Here's a quick overview:

Key Features of DbContext:

1. Database Connection Management: It handles the connection to the database.


2. Querying and Saving Data: You can use LINQ queries to retrieve data and call methods like
SaveChanges() to persist changes to the database.
3. Change Tracking: It keeps track of changes made to entities so that only the modified data is
updated in the database.
4. Model Configuration: It configures the database schema and relationships between entities.
5. Transaction Management: It supports transactions to ensure data consistency.
*Database Connection String in Entity Framework Core

In Entity Framework Core, a database connection string is essential for establishing a connection between
your application and the database.

It contains details like the server name, database name, credentials, and other settings

Here's how you can manage and use connection strings:

Way to Provide Connection Strings

Using appsettings.json:

Store the connection string in the appsettings.json file for better maintainability:

{
"ConnectionStrings": {
"DefaultConnection":
"Server=(localdb)\\MSSQLLocalDB;Database=YourDatabaseName;Trusted_Connection=True;"
}
}

*CRUD in asp.net core MVC

CRUD (Create, Read, Update, Delete) operations are fundamental in ASP.NET Core MVC for managing
data.
Step-1) Install these 3 packages..

Step-2) Create Model Class

public class Student


{
[Key]
public int rollnum { get; set; }
public string name { get; set; }
public string city { get; set; }
}

Step-3) Create DBContext Class

public class ApplicationDBContext:DbContext


{
public ApplicationDBContext(DbContextOptions dbContextOptions):base(dbContextOptions)
{}

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


}
Step-4) Add the connection string to appsettings.json:
json

"ConnectionStrings": {
"DefaultConnection":
"Server=SANGOLA123\\SQLEXPRESS;Database=MySTUDDB;Trusted_Connection=True;TrustServerCertificat
e=True;"

Step-5) In Program.cs configure the DbContext:

builder.Services.AddDbContext<ApplicationDBContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

Step-6): Create the Controller

Generate a scaffolded controller to handle CRUD operations using Entity Framework Core:

1. Right-click on the "Controllers" folder.


2. Select "Add > Controller > MVC Controller with views, using Entity Framework".
3. Choose the model (Student) and DbContext (StudentDbContext) to generate CRUD views and
actions automatically.

*Entity States in Entity Framework Core

In Entity Framework Core, entity states represent the state of an entity in relation to the database and the
DbContext.

These states help EF Core determine what actions to perform on the database when SaveChanges() is
called.

The Five Entity States:

1. Added:
o The entity is being tracked by the context but does not yet exist in the database.
o EF Core will issue an INSERT command for this entity during SaveChanges().
2. Unchanged:
o The entity is being tracked and exists in the database, but its property values have not been
modified.
o EF Core will not issue any database commands for entities in this state.
3. Modified:
o The entity is being tracked and exists in the database, but some or all of its property values
have been changed.
o EF Core will issue an UPDATE command for the modified properties during SaveChanges().
4. Deleted:
o The entity is being tracked and exists in the database, but it has been marked for deletion.
o EF Core will issue a DELETE command for this entity during SaveChanges().
5. Detached:
o The entity is not being tracked by the context.
o EF Core will not perform any database operations on detached entities.
How to Check or Set Entity States:

You can use the EntityEntry.State property to check or modify the state of an entity:

var entity = context.Employees.Find(1);


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

*Data Annotation Attributes in Entity Framework Core-

In Entity Framework Core, Data Annotation Attributes are used to configure the model by decorating
classes and properties with metadata.

Here's a breakdown of the attributes you mentioned:

1. Table Attribute

• Specifies the database table name and schema for an entity.

[Table("Employees", Schema = "HR")]


public class Employee { ... }

2. Column Attribute

• Configures the database column name, data type, and order.

[Column("EmpName", TypeName = "nvarchar(100)")]


public string Name { get; set; }

3. Key Attribute

• Marks a property as the primary key.

[Key]
public int EmployeeId { get; set; }

4. ForeignKey Attribute

• Specifies the foreign key property for a navigation property.

[ForeignKey("DepartmentId")]
public Department Department { get; set; }

5. Index Attribute

• Defines an index on a property or set of properties (introduced in EF Core 5.0).

[Index(nameof(Name), IsUnique = true)]


public string Name { get; set; }

6. InverseProperty Attribute

• Specifies the inverse navigation property in a relationship.


[InverseProperty("Manager")]
public ICollection<Employee> Subordinates { get; set; }

7. NotMapped Attribute

• Excludes a property from being mapped to a database column.

[NotMapped]
public string FullName { get; set; }

8. Required Attribute

• Makes a property non-nullable.

[Required]
public string Name { get; set; }

9. MaxLength and MinLength Attributes

• Restricts the length of string or array properties.

[MaxLength(50)]
[MinLength(5)]
public string Name { get; set; }

10. DatabaseGenerated Attribute

• Specifies how the database generates values for a property.

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmployeeId { get; set; }

11. TimeStamp Attribute

• Marks a property as a concurrency token.

[Timestamp]
public byte[] RowVersion { get; set; }

12. ConcurrencyCheck Attribute

• Ensures a property is checked for concurrency conflicts.

[ConcurrencyCheck]
public string Name { get; set; }

*Relationships in Entity Framework Core

Entity Framework Core (EF Core) simplifies managing relationships between entities in your data model.

In Entity Framework Core (EF Core), relationships define how entities (classes) are related to each other
in your data model.

These relationships map to database-level relationships, such as foreign keys.


Here are some examples of relationships with code snippets:

1. One-to-One Relationship

A User entity might have one Profile entity:

public class User


{
public int Id { get; set; }
public Profile Profile { get; set; }
}

public class Profile


{
public int Id { get; set; }
public int UserId { get; set; }
public User User { get; set; }
}

2. One-to-Many Relationship

A Blog entity can have many Post entities:

public class Blog


{
public int Id { get; set; }
public ICollection<Post> Posts { get; set; }
}

public class Post


{
public int Id { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}

3. Many-to-Many Relationship

A Student entity can be associated with many Course entities, and vice versa:

public class Student


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

public class Course


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

*Self-Referencing Relationship

A self-referencing relationship in Entity Framework Core is when an entity has a relationship with
itself.

OR
A self-referencing relationship in Entity Framework Core occurs when an entity has a relationship with
another instance of the same entity type.

This is useful for scenarios like organizational hierarchies, threaded comments, categories with
subcategories, etc.

Example: Employee-Manager Relationship

This is used for modeling hierarchical data, such as an Employee entity where each employee can have a
manager who is also an employee.

public class Employee


{
public int EmployeeId { get; set; }
public string Name { get; set; }
public int? ManagerId { get; set; } // Foreign key
public Employee Manager { get; set; } // Navigation property
public ICollection<Employee> Subordinates { get; set; } = new List<Employee>(); //
Navigation property
}

Explanation:

• ManagerId: Acts as the foreign key referencing the EmployeeId of the manager.
• Manager: Navigation property pointing to the manager.
• Subordinates: Collection navigation property representing employees managed by this employee.

Configuring in DbContext

You can configure this relationship using Fluent API:

protected override void OnModelCreating(ModelBuilder modelBuilder)


{
modelBuilder.Entity<Employee>()
.HasOne(e => e.Manager)
.WithMany(e => e.Subordinates)
.HasForeignKey(e => e.ManagerId);
}

This setup allows you to query hierarchical data, such as retrieving all subordinates of a specific manager or
finding the manager of an employee.

*Asynchronous Programming with Entity Framework Core

Asynchronous programming in Entity Framework Core (EF Core) allows you to perform database
operations without blocking the main thread.

This is particularly useful for improving the responsiveness of applications, especially in scenarios like web
applications or UI-based apps. Here’s a quick overview:

Why Use Asynchronous Programming?

• Improved Responsiveness: Keeps the UI responsive in client applications.


• Better Scalability: Frees up threads to handle more requests in web applications.
• Efficient Resource Usage: Avoids blocking threads during I/O-bound operations like database
queries.
Common Asynchronous Methods in EF Core

EF Core provides asynchronous counterparts for most synchronous methods:

• SaveChangesAsync(): Saves changes to the database.


• ToListAsync(): Converts a query result to a list asynchronously.
• FindAsync(): Finds an entity by its primary key asynchronously.
• FirstOrDefaultAsync(): Retrieves the first entity that matches a condition asynchronously.

Important Notes

• Always use await with asynchronous methods to ensure proper execution.


• Avoid running multiple asynchronous operations on the same DbContext instance simultaneously, as
EF Core does not support parallel operations on a single context.

*Disconnected Entities in Entity Framework Core

Disconnected entities in Entity Framework Core (EF Core) refer to entities that are no longer tracked by
a DbContext instance.

This typically happens in scenarios like web applications, where entities are fetched from the database,
manipulated outside the scope of the DbContext, and then returned for further processing.

Managing disconnected entities requires explicit state management when reattaching them to a new
DbContext.

Key Concepts:

1. Connected Entities: Actively tracked by the DbContext. Changes are automatically detected and
saved.
2. Disconnected Entities: Not tracked by any DbContext. Their state must be explicitly set when
reattaching.

Example: Handling Disconnected Entities

Suppose you fetch a Product entity, modify it in a client application, and then save it back to the database.

Fetching the Entity:

using (var context = new MyDbContext())


{
var product = context.Products.FirstOrDefault(p => p.Id == 1);
// Send the product to the client
}

Reattaching and Saving:

using (var context = new MyDbContext())


{
var updatedProduct = new Product { Id = 1, Name = "Updated Product" };
context.Entry(updatedProduct).State = EntityState.Modified;
await context.SaveChangesAsync();
}
Important Notes:

• State Management: Use context.Entry(entity).State to set the state (Added, Modified,


Deleted, etc.).
• Auto-Generated Keys: If the primary key is not set, EF Core assumes the entity is new and inserts
it.
• ChangeTracker.TrackGraph: Useful for handling complex object graphs with disconnected
entities.

*Stored Procedures in Entity Framework Core-

Stored procedures in Entity Framework Core allow you to execute predefined SQL commands directly
from your application, which can be useful for complex queries or operations that require optimized
performance.

Here’s how you can work with stored procedures in EF Core:

• Using FromSqlRaw: You can retrieve data from stored procedures using
DbSet<TEntity>.FromSqlRaw().

Example:

var students = context.Students.FromSqlRaw("EXEC GetStudents @FirstName", new


SqlParameter("@FirstName", "John")).ToList();

• Executing Non-Query Stored Procedures: If your stored procedure performs insert, update, or
delete operations, use ExecuteSqlRaw():

context.Database.ExecuteSqlRaw("EXEC UpdateStudentMark @StudentId, @NewMark", new


SqlParameter("@StudentId", 1), new SqlParameter("@NewMark", 90));

• Limitations:
o Stored procedures must return all columns of an entity type.
o They cannot return related data (i.e., no joins).
o Insert, update, and delete procedures cannot be mapped directly to entities.

Example: Step-1)Create a Stored Procedure in your database.

CREATE PROCEDURE GetStudents


AS
BEGIN
SELECT rollnum, name, city FROM student_info
END

Step-2) Define a Model

public class Student


{
[Key]
public int rollnum { get; set; }
public string name { get; set; }
public string city { get; set; }
}
Step-3) Define a StudentDBContext and Modify your DbContext class to execute the stored
procedure.

public class StudentDBContext:DbContext


{
public StudentDBContext(DbContextOptions contextOptions) : base(contextOptions)
{

DbSet<Student> Student_info { get; set; }

public List<Student> GetStudentsFromStoredProcedure()


{
return Student_info.FromSqlRaw("EXEC GetStudents").ToList();
}

Step-4) Create ConnectionString in appSettings.json

"ConnectionStrings": {
"MyConn":
"Server=SAANVI\\SQLEXPRESS;Database=MYDB;Trusted_Connection=True;TrustServerCertificate=Tr
ue;"
},

Step-5) Register the Connection String in Program.cs

builder.Services.AddDbContext<StudentDBContext>(options=>options.UseSqlServer(builder.Configuratio
n.GetConnectionString("MyConn")));

Step-6) Create the Controller In your Controller, call the method to fetch data using the stored
procedure.

public class StudentController : Controller


{
private readonly StudentDBContext _context;
public StudentController(StudentDBContext context)
{
_context = context;
}

public IActionResult Index()


{
var stud = _context.GetStudentsFromStoredProcedure();
return View(stud);
}
}

Step-7)Create a View Finally, create a view (Index.cshtml) to display the students:

<h1>Index</h1>

@model List<Student>

<table class="table-bordered" >


<tr>
<th>RollNumber</th>
<th>Name</th>
<th>City</th>
</tr>
@foreach (var stud in Model)
{
<tr>
<td>@stud.rollnum</td>
<td>@stud.name</td>
<td>@stud.city</td>
</tr>
}
</table>

*Transactions in Entity Framework Core

What is a Transaction?

A transaction is a unit of work where all operations must succeed, or none are applied.

Transactions in Entity Framework Core ensure that multiple database operations are executed as a single
unit, meaning they either all succeed or all fail, maintaining data integrity.

This is crucial when you're:

• Updating multiple tables


• Performing a series of inserts/updates/deletes
• Calling stored procedures with side effects
• Mixing EF Core with raw SQL

EF Core uses transactions automatically by default when SaveChanges() is called — but you can
manually control them when needed.

Ways to Handle Transactions in EF Core:

1. Implicit Transactions: By default, SaveChanges() wraps operations in a transaction. If any


command fails, all changes are rolled back.

context.SaveChanges();

2. Manual/Explicit Transactions: You can manually control transactions using


BeginTransaction(), Commit(), and Rollback().
using var transaction = context.Database.BeginTransaction();
try
{
context.Orders.Add(new Order { OrderDate = DateTime.Now });
context.SaveChanges();

transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}

3. Asynchronous Transactions: EF Core supports async transaction handling.

await using var transaction = await context.Database.BeginTransactionAsync();

4. Savepoints: EF Core automatically creates savepoints within transactions, allowing partial rollbacks.

Here’s a simple program demonstrating transactions in Entity Framework Core:

Example: Using Transactions in EF Core


using System;
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext


{
public DbSet<Order> Orders { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)


{
optionsBuilder.UseSqlServer("YourConnectionStringHere");
}
}

public class Order


{
public int Id { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
}

class Program
{
static void Main()
{
using var context = new AppDbContext();
using var transaction = context.Database.BeginTransaction();

try
{
var order1 = new Order { ProductName = "Laptop", Quantity = 1 };
var order2 = new Order { ProductName = "Mouse", Quantity = 2 };

context.Orders.Add(order1);
context.Orders.Add(order2);
context.SaveChanges();

transaction.Commit();
Console.WriteLine("Transaction committed successfully.");
}
catch (Exception ex)
{
transaction.Rollback();
Console.WriteLine($"Transaction rolled back due to error: {ex.Message}");
}
}
}

Explanation:

• BeginTransaction() starts a transaction.


• SaveChanges() commits the changes.
• Commit() ensures all operations are saved.
• Rollback() undoes changes if an error occurs.

*Migrations in Entity Framework Core

• Migrations in Entity Framework Core allow you to incrementally update your database schema to
match changes in your application's data model, without losing existing data.
• It's part of the Code-First approach, where your C# classes drive the shape of your database.

*Database Seeding in Entity Framework Core

Database seeding in Entity Framework Core allows you to populate your database with initial data when
it's created or migrated.

This is useful for setting up default values, test data, or essential records.

Way to Seed Data in EF Core

1. Using HasData in OnModelCreating


You can define seed data within your DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)


{
modelBuilder.Entity<Product>().HasData(
new Product { Id = 1, Name = "Laptop", Price = 1000 },
new Product { Id = 2, Name = "Mouse", Price = 20 }
);
}

This data is applied when running dotnet ef migrations add and dotnet ef database update.

Entity Framework Core Development Approaches:


Entity Framework Core supports two development approaches. They are as follows:

1. Code-First Approach: In this approach, the data model (classes) is created first, and Entity
Framework Core generates the database schema based on the model.

2. Database-First Approach: This approach is used when an existing database is available. Entity
Framework Core can generate the data model (classes) based on the database schema.
1)EF Core Code First Approach:

In the EF Core Code First Approach, first, we need to create our application domain classes, such as Student,
Branch, Address, etc., and a special class (called DBContext Class) that derives from the Entity
Framework Core DbContext class.

Developers can configure relationships, constraints, and database mappings using Data Annotations and
Fluent API. Then, based on the application domain classes and DBContext class, the EF Core creates the
database and related tables. For a better understanding, please have a look at the following diagram.

Example-

Step-1) Install EF Core NuGet Package: Add the required Entity Framework Core packages to your
project:

Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Design

Step-2) Create A Model Class And DBContext Class

using System.ComponentModel.DataAnnotations;

namespace CodeFirstEF.Models
{
public class Student
{
[Key]
public int rollnum { get; set; }
public string name { get; set; }
public int mbnum { get; set; }
}
}

---------------------------------------------------------------------------------------------

using Microsoft.EntityFrameworkCore;
namespace CodeFirstEF.Models
{
public class StudentDBContext:DbContext
{
public StudentDBContext(DbContextOptions options):base(options)
{

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

}
}
Step-3) Configure the Connection String

You’ll need to configure your connection string in appsettings.json.

appsettings.json:

"ConnectionStrings": {
"MyConn":
"Server=SAANVI\\SQLEXPRESS;Database=STUD;Trusted_Connection=True;TrustServerCertificate=Tru
e;"
},

Step-4) Register the Connection String in Program.cs

builder.Services.AddDbContext<StudentDBContext>(options=>options.UseSqlServer(builder.Configuratio
n.GetConnectionString("MyConn")));

Step-5) Creating the Migration

Now that we have the model and DbContext, let’s create a migration to generate the database schema.

1. Open your Tools > Package Manager Console in Visual Studio.


2. Run the following commands to create and apply a migration:

PM> Add-Migration InitialCreate

PM> Update-Database

2)EF Core Database First Approach:

Use the EF Core Database First Approach if you have an existing database and database tables are already
there.

In the database-first approach, the EF Core creates the DBContext and Domain Classes based on the
existing database schema.

This approach is suitable for scenarios where the application code does not control the database schema or
when working with existing databases. For a better understanding, please have a look at the following
diagram.
So, the Database First approach starts with an existing database schema. EF Core generates the domain
classes that map to the database tables. This approach is suitable for applications that need to work with an
existing database.

Example-

Step-1) Create DB named STUD and Create Table students

Here's an example of SQL code to create a table named students in SQL Server:

CREATE TABLE students (


StudentID INT PRIMARY KEY,
FirstName NVARCHAR(50) NOT NULL,
LastName NVARCHAR(50) NOT NULL,
DateOfBirth DATE,
Gender NVARCHAR(10),
ContactNumber NVARCHAR(15),
Email NVARCHAR(50),
Address NVARCHAR(100)
);

Step-2) Create ASP.Net Core MVC Application and Install following 3 Packages

Microsoft.EntityFrameworkCore.Tools

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Design

Step-3) Execute Following command into Package Manager Console-

Run the following command in the Package Manager Console to generate models and DbContext based on
an existing database:

Scaffold-DbContext
"Server=SAANVI\\SQLEXPRESS;Database=STUD;Trusted_Connection=True;TrustServerCertificate=Tru
e;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

You might also like