Lazy Loading in Entity Framework Core

Lazy Loading in Entity Framework (EF) Core

In this article, I will discuss Lazy Loading in Entity Framework (EF) Core with Examples. Please read our previous article discussing Eager Loading in Entity Framework Core with Examples. At the end of this article, you will understand the following pointers:

  1. What is Lazy Loading in Entity Framework Core?
  2. Example to Understand Lazy Loading in Entity Framework Core
  3. How to Implement Lazy Loading in EF Core?
  4. Lazy Loading With Proxies in EF Core
  5. Lazy Loading Without Proxies in Entity Framework Core
  6. How to Disable Lazy Loading in EF Core?
  7. Advantages and Disadvantages of using Lazy Loading in EF Core
  8. When to use Lazy Loading in EF Core?
  9. What is the Difference Between Eager Loading and Lazy Loading in EF Core?
  10. Which is good – Eager Loading or Lazy Loading in Entity Framework Core?
What is Lazy Loading in Entity Framework Core?

Lazy Loading is a Process where Entity Framework Core loads the related entities on demand. That means the related entities or child entities are loaded only when it is being accessed for the first time. So, in simple words, we can say that Lazy loading delays the loading of related entities until you specifically request it. 

Lazy loading in Entity Framework Core is a pattern where related data is automatically loaded from the database as soon as the navigation property on an entity is accessed for the first time. This approach can simplify the code and avoid loading unnecessary data. 

Example to Understand Lazy Loading in Entity Framework Core:

Let us understand Lazy Loading in EF Core with an example. Please have a look at the following Student entity. Looking at the Student class, you will find a navigation property for the StudentAddress entity. At the same time, you will also find a navigation property for Standard and a collection navigation property for Courses Entities.

Example to Understand Lazy Loading in Entity Framework

In Lazy Loading, the context object first loads the Student entity data from the database. Then, it will load the related entities when you access those navigation properties for the first time. If you are not accessing the Navigation Properties, it will not load those related data from the database.

For example, when executing the below statement, the context object will only load the Student data using a SELECT SQL Statement. It will not load the related StudentAddress, Standard, or Courses table data.

Student? student = context.Students.FirstOrDefault(std => std.StudentId == 1);

Later, suppose you execute the below statement, i.e., access the StudentAddress Property for the First Time. In that case, the Context object will issue a SELECT SQL Statement and load the related StudentAddress data from the database table.

StudentAddress? studentAddress = student?.StudentAddress;

Similarly, when you execute the below statement, the Context object will generate and execute another SELECT SQL Statement to fetch the related data from the Standards database table.

Standard? standard = student?.Standard;

How to Implement Lazy Loading in EF Core?

We can implement Lazy loading in Entity Framework Core in two ways. They are as follows:

  1. Lazy Loading With Proxies
  2. Lazy loading Without Proxies

Lazy Loading With Proxies in EF Core:

To enable Lazy Loading using Proxies in Entity Framework Core, the first step is to install the Proxy Package provided by Microsoft. This can be done by installing Microsoft.EntityFrameworkCore.Proxies package, which will add all the necessary proxies. There are three steps involved in enabling Lazy Loading using Proxies.

  1. Install Proxies Package
  2. Enable Lazy Loading using UseLazyLoadingProxies
  3. Mark the Navigation Property as a Virtual
Step 1: Install Microsoft.EntityFrameworkCore.Proxies Package

So, open NuGet Package Manager UI by selecting Tools => NuGet Package Manager => Manage NuGet Packages for Solution from the Visual Studio Menu, which will open the following window. From this window, select the Search tab, then search for Microsoft.EntityFrameworkCore.Proxies package and select Microsoft.EntityFrameworkCore.Proxies package and click the Install button, as shown in the image below.

Install Microsoft.EntityFrameworkCore.Proxies Package

Once you click the Install button, it will open the Preview Changes window to tell what packages will be installed. Review the changes and click the OK button in the image below.

Install Microsoft.EntityFrameworkCore.Proxies Package

Once you click on the OK button, it will open the License Acceptance window. Click on the I Accept button as shown in the below image.

Install Microsoft.EntityFrameworkCore.Proxies Package

Once you click on the I Accept button, it will install the package, and you can verify the package inside the Dependencies => Packages folder of your project, as shown in the image below.

Install Microsoft.EntityFrameworkCore.Proxies Package

Alternatively, you can also Install Microsoft.EntityFrameworkCore.Proxies package using the Package Manager Console and .NET Core CLI Command as follows:

  1. [Package Manager Console]: install-package Microsoft.EntityFrameworkCore.Proxies
  2. [Dotnet CLI]: dotnet add package Microsoft.EntityFrameworkCore.Proxies
Step 2: Enable Lazy Loading using UseLazyLoadingProxies

Once you Install Microsoft.EntityFrameworkCore.Proxies package, then you need to use the UseLazyLoadingProxies method to enable the Lazy Loading in Entity Framework Core within the OnConfiguring method of the DbContext class.

optionsBuilder.UseLazyLoadingProxies();

So, modify the EFCoreDbContext context class as follows:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated the Database Script
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Enabling Lazy Loading
            optionsBuilder.UseLazyLoadingProxies();

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        public virtual DbSet<Course> Courses { get; set; }

        public virtual DbSet<Standard> Standards { get; set; }

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

        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }

        public virtual DbSet<Teacher> Teachers { get; set; }
    }
}
Step3: Mark the Navigation Property as Virtual

Finally, we need to mark the navigation property as virtual, which we want to Laod Lazily. So, if you see our Student, we have already marked the Navigation Properties as Virtual, as shown in the below image.

Mark the Navigation Property as Virtual

Note: If you have not marked the navigation properties as virtual, then please add the virtual keyword, and then, as we already discussed, whenever we add or update domain classes, we need to sync the database with the model using add-migration and update-database commands using Package Manager Console or .NET Core CLI. 

Using Lazy Loading in EF Core:
  • How It Works: When you access a navigation property, EF Core checks if the related data is already loaded. If not, it automatically queries the database to load the data.
  • Usage: Lazy loading is useful when you’re unsure whether you’ll need related data and want to avoid the overhead of loading it unnecessarily.

Now, modify the Main method of the Program class as follows to use Lazy Loading in Entity Framework Core. 

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var context = new EFCoreDbContext();

                //Loading the particular student data only
                //Here, it will only load the Student Data, no related entities
                Student? student = context.Students.FirstOrDefault(std => std.StudentId == 1);
                Console.WriteLine($"Firstname: {student?.FirstName}, Lastname: {student?.LastName}");
                Console.WriteLine();

                //Loading the Student Address (it will execute Separate SQL query)
                StudentAddress? studentAddress = student?.StudentAddress;
                Console.WriteLine($"AddresLin1 {studentAddress?.Address1}, AddresLin2 {studentAddress?.Address2}");
                Console.WriteLine();

                //Loading the Standard (it will execute Separate SQL query)
                Standard? standard = student?.Standard;
                Console.WriteLine($"StandardName: {standard?.StandardName}, Description: {standard?.Description}");
                Console.WriteLine();

                //Loading the Course (it will execute separate SQL query)
                //var courses = student?.Courses;
                //if( courses != null )
                //{
                //    foreach (var course in courses)
                //    {
                //        Console.WriteLine($"CourseName: {course.CourseName}");
                //    }
                //}
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}
Output:

Using Lazy Loading in EF Core

As you can see in the above output, it is issuing three different Select Statements to load the data from the database. This means it is using Lazy Loading to load the related data. Further, you can see that it is not loading the Courses table data, as we have commented on the statement accessing the Courses navigation property.

Note: Lazy loading can lead to the N+1 problem, which causes unnecessary database roundtrips.

Lazy Loading Without Proxies in Entity Framework Core:

The second approach to enabling Lazy Loading in Entity Framework Core is using the ILazyLoader interface. Implementing Lazy-Loading Without Proxies in EF Core is done by injecting the ILazyLoader service into an entity.

  1. The ILazyLoader interface is responsible for loading navigation properties that have not yet been loaded.
  2. The feature can be easily integrated into the main component of the database. That is to the Principal Entity.
  3. To use the ILazyLoader, it is necessary to install Microsoft.EntityFrameworkCore.Abstraction Package.
Step 1: Install Microsoft.EntityFrameworkCore.Abstraction Package

So, open NuGet Package Manager UI by selecting Tools => NuGet Package Manager => Manage NuGet Packages for Solution from the Visual Studio Menu, which will open the following window. From this window, select the Search tab, then search for Microsoft.EntityFrameworkCore.Abstraction package and select Microsoft.EntityFrameworkCore.Abstraction package and click the Install button, as shown in the image below.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Once you click the Install button, it will open the Preview Changes window to tell what packages will be installed. Review the changes and click the OK button in the image below.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Once you click on the OK button, it will open the License Acceptance window. Click on the I Accept button as shown in the below image.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Once you click on the I Accept button, it will install the package, and you can verify the package inside the Dependencies => Packages folder of your project, as shown in the image below.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Alternatively, you can also Install Microsoft.EntityFrameworkCore.Abstraction package using the Package Manager Console and .NET Core CLI Command as follows:

  1. [Package Manager Console]: install-package Microsoft.EntityFrameworkCore.Abstraction
  2. [Dotnet CLI]: dotnet add package Microsoft.EntityFrameworkCore.Abstraction
Step 2: Alter the Principal Entity

Once you install Microsoft.EntityFrameworkCore.Abstraction Package: You must alter the Principal entity to include the following.

  1. A using directive for Microsoft.EntityFrameworkCore.Infrastructure
  2. A private field for the ILazyLoader instance
  3. An Empty Constructor and One Parameterized Constructor that takes an ILazyLoader as a parameter to Initialize the ILazyLoader instance.
  4. A Private field for the Navigation Property
  5. A Public Getter and Setter property for the Private Navigation Field that uses the ILazyLoader.Load method.

In our example, the Student Entity is the Principal Entity. Please modify the Student Entity to include the above-discussed thing so it can load the related entities lazily. 

//Adding the namespace
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace EFCoreCodeFirstDemo.Entities
{
    public class Student
    {
        //A private field for the ILazyLoader instance
        private readonly ILazyLoader _lazyLoader;

        //An empty constructor 
        public Student()
        {
        }

        //one parameterized that takes an ILazyLoader as a parameter to
        //Initialize the ILazyLoader instance
        public Student(ILazyLoader lazyLoader)
        {
            _lazyLoader = lazyLoader;
        }

        public int StudentId { get; set; }

        public string? FirstName { get; set; }

        public string? LastName { get; set; }

        public int? StandardId { get; set; }

        //Private Field For Standard Navigation Property
        private Standard _Standard;

        //Public Setter and Getter Property for the Private _Standard Field
        public Standard Standard
        {
            get => _lazyLoader.Load(this, ref _Standard);
            set => _Standard = value;
        }

        //public virtual StudentAddress? StudentAddress { get; set; }

        //Private Field For StudentAddress Navigation Property
        private StudentAddress _StudentAddress;

        //Public Setter and Getter Property for the Private _StudentAddress Field
        public StudentAddress StudentAddress
        {
            get => _lazyLoader.Load(this, ref _StudentAddress);
            set => _StudentAddress = value;
        }

        //Private Field For Course Collection Navigation Property
        private ICollection<Course> _Courses = new List<Course>();

        //Public Setter and Getter Property for the Private _Courses Field
        public ICollection<Course> Courses
        {
            get => _lazyLoader.Load(this, ref _Courses);
            set => _Courses = value;
        }
    }
}

Next, modify the EFCoreDbContext class as follows. Here, we are removing the optionsBuilder.UseLazyLoadingProxies() method call, which enables Lazy Loading using Proxies.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated the Database Script
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        public virtual DbSet<Course> Courses { get; set; }

        public virtual DbSet<Standard> Standards { get; set; }

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

        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }

        public virtual DbSet<Teacher> Teachers { get; set; }
    }
}

We don’t need to make any changes to the Main method. So, now, run the application, and you should get the following output as expected. As you can see, EF Core uses separate SELECT SQL Statements to load the related entities.

Lazy Loading Without Proxies in Entity Framework Core

How to Disable Lazy Loading in EF Core?

Suppose you want to disable Lazy Loading for the whole application. In that case, you need to use the LazyLoadingEnabled property of the ChangeTracker class and set this property value to true within the constructor of the context class, as shown in the image below.

How to Disable Lazy Loading in EF Core?

So, modify the EFCoreDbContext class to disable Lazy Loading for the whole application in Entity Framework Core.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
            //Disabling Lazy Loading
            this.ChangeTracker.LazyLoadingEnabled = false;
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated the Database Script
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        public virtual DbSet<Course> Courses { get; set; }

        public virtual DbSet<Standard> Standards { get; set; }

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

        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }

        public virtual DbSet<Teacher> Teachers { get; set; }
    }
}

With these changes in place, if you run the application, you will see that the related entities will not be loaded when we access them, as shown in the image below.

How to Disable Lazy Loading in EF Core?

Note: The default value of LazyLoadingEnabled is set to true. Although we have not set this property value to true, Lazy Loading is still working in our application. Even if you want, then while accessing the data, you can enable and disable lazy loading.

For a better understanding, please have a look at the following example. In the example below, we disable the Lazy Loading using the statement context after fetching the Student data, i.e., ChangeTracker.LazyLoadingEnabled = false; hence, it will not load the Standard data. Then, we again enabled the Lazy loading by using the context.ChangeTracker.LazyLoadingEnabled = true; statement, and then we are accessing the StudentAddress navigation property, and this time, as Lazy Loading is enabled, it will issue a separate SELECT SQL Statement and load the Student Address data.

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var context = new EFCoreDbContext();

                //Loading the particular student data only
                //Here, it will only load the Student Data, no related entities
                Student? student = context.Students.FirstOrDefault(std => std.StudentId == 1);
                Console.WriteLine($"Firstname: {student?.FirstName}, Lastname: {student?.LastName}");
                Console.WriteLine();

                //I want to Disable Lazy Loading Here
                context.ChangeTracker.LazyLoadingEnabled = false;

                //As Lazy Loading is Disabled so, it will not load the Standard data
                Standard? standard = student?.Standard;
                Console.WriteLine($"StandardName: {standard?.StandardName}, Description: {standard?.Description}");
                Console.WriteLine();

                //I want to Enable Lazy Loading Here
                context.ChangeTracker.LazyLoadingEnabled = true;

                //As Lazy Loading is Enabled so, it will load the StudentAddress data
                StudentAddress? studentAddress = student?.StudentAddress;
                Console.WriteLine($"AddresLin1 {studentAddress?.Address1}, AddresLin2 {studentAddress?.Address2}");
                Console.WriteLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}
Output:

Advantages and Disadvantages of using Lazy Loading in EF Core

Advantages of using Lazy Loading in EF Core:

Lazy loading in Entity Framework Core (EF Core) offers several advantages that can simplify code, improve memory usage, and provide a more efficient approach to data retrieval. Here are some key advantages of using Lazy Loading in Entity Framework Core:

  • Improved Initial Performance: Lazy loading defers the loading of related data until it is actually needed, which can reduce the time and resources required to load an entity initially. This can be particularly beneficial in scenarios where only a portion of the related data is needed.
  • Simplified Data Access Code: Lazy loading simplifies the data access code by automatically loading related entities. This means developers do not need to include related entities in their queries explicitly. It can lead to more readable and maintainable code, as the logic for loading related data is abstracted away.
  • Dynamic Data Retrieval: Only the data that is actually used is loaded, which can be efficient in scenarios where the complete dataset is not needed upfront.
  • Flexibility: It provides flexibility in accessing related data – the application can navigate through relationships in the object graph without having to pre-plan all data loading in advance.
  • Potentially Lower Memory Usage: In scenarios where a small portion of related data is used, lazy loading can help keep the memory footprint low by not loading unused data.
  • Useful in Certain Scenarios: In complex models with deep object graphs, lazy loading can prevent the unnecessary loading of vast amounts of related data, which might never be used.
  • User-Driven Data Access: In user-interactive applications where the user navigates and drives data access, lazy loading can improve responsiveness and reduce resource consumption.
Disadvantages of using Lazy Loading in EF Core

While lazy loading in Entity Framework Core (EF Core) offers certain benefits, it also has disadvantages and pitfalls. Here are some key disadvantages of using lazy loading:

  • N+1 Query Problem: Lazy loading can lead to the N+1 query problem, where accessing each object in a collection results in a separate query to the database. This can significantly impact performance, especially in scenarios with large datasets.
  • Unintended Queries: It’s easy to unintentionally trigger database queries without realizing it, especially when accessing properties in a loop or during serialization.
  • Hidden Database Calls: Because database queries are made implicitly, tracking and debugging them can be harder. This can make performance tuning and debugging more challenging.
  • Testing Complexity: Writing unit tests can be more complex since you need to account for the database calls that are made implicitly.
  • Potential for Increased Memory Usage: Lazy loading can lead to increased memory consumption if not managed carefully, especially when large amounts of data are loaded into memory that might not be necessary.
  • Tight Coupling with Entity Framework: Entities often need to be aware of the context (e.g., by including virtual properties for navigation), which can lead to a tighter coupling between your domain models and EF Core.
  • Unpredictable Behavior in Disconnected Scenarios: In scenarios where the context is disposed (like in Web applications or Web APIs), lazy loading can lead to exceptions when accessing navigation properties, as the context is no longer available to load related data.
  • Risk of Data Inconsistencies: In long-running contexts, lazy loading can result in data inconsistencies if related data changes in the database after the initial data is loaded but before the lazy load occurs.
  • Increased Complexity in Transaction Management: Managing transactions can be more complex with lazy loading, as the boundaries of database interactions are less clear.

What is the Difference Between Eager Loading and Lazy Loading in EF Core?

In Entity Framework Core, eager and lazy loading are techniques used to load related data from the database, but they differ significantly in how and when the data is loaded.

Eager Loading in EF Core:

Eager loading is the process of loading the main entity and its related entities from the database in a single query. This is typically done using the Include and ThenInclude methods in a LINQ query.

Characteristics of Eager Loading in EF Core:
  • Single Query: Related data is loaded in the same query as the main entity, typically resulting in a more complex query with joins.
  • Immediate Loading: All specified related data is loaded upfront, regardless of whether it will be used.
  • Controlled Loading: You have explicit control over which related entities are loaded.
  • Performance: This can result in more efficient loading with fewer round trips to the database, which is especially beneficial for known data requirements.
Lazy Loading in EF Core:

On the other hand, Lazy Loading defers the loading of related data until it is explicitly accessed for the first time.

Characteristics of Lazy Loading in EF Core:
  • Separate Queries: Related data is loaded in separate queries, each triggered when a navigation property is accessed for the first time.
  • Delayed Loading: Data is loaded on-demand, which can save resources if the related data is never accessed.
  • Automatic Loading: EF Core automatically loads the related data, which can simplify code but may lead to unintended queries.
  • Potential for Performance Issues: This can lead to the N+1 query problem, where multiple queries are executed, potentially impacting performance.
Key Differences Between Eager Loading and Lazy Loading in EF Core:
  • Query Strategy: Eager loading retrieves all data in one query, while lazy loading retrieves data in multiple queries.
  • Performance: Eager loading can be more efficient for known data needs, avoiding multiple round trips. Lazy loading can be more efficient for conditional data access but may lead to performance issues if not used carefully.
  • Data Retrieval: Eager loading retrieves all related data upfront, while lazy loading retrieves it as needed.
  • Control and Visibility: Eager loading provides more control and visibility over the data retrieval process, whereas lazy loading abstracts this away.
  • Use Cases: Eager loading is suitable when you know you need related data for each entity. Lazy loading is useful when you need to access related data conditionally or in a non-predictable manner.
Which is good – Eager Loading or Lazy Loading in Entity Framework Core?

Before deciding which approach to use, we must consider the application requirements and goals. Lazy Loading and Eager Loading have strengths and weaknesses, and we have observed significant performance differences when using each method to accomplish the same task.

The choice between eager and lazy loading in Entity Framework Core (EF Core) depends on your specific application requirements, data access patterns, and performance considerations. Eager loading can be more efficient for complete and predictable data sets, while lazy loading can benefit dynamic, user-driven data access patterns.

In the next article, I will discuss Explicit Loading in Entity Framework Core with Examples. In this article, I try to explain the Lazy Loading in Entity Framework Core with Examples, and I hope you enjoyed this Lazy Loading in EF Core with Examples article. Please give your valuable feedback and suggestions about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *