MSDN

Working with Entities

Entities are the core building blocks of the Entity Framework. They represent objects in your application domain that map to tables in your database. Understanding how to create, manipulate, and manage entities is fundamental to using Entity Framework effectively.

What are Entities?

In the context of Entity Framework, an entity is a .NET object that represents a row in a database table. Each property of the entity maps to a column in that table. Entity Framework manages the lifecycle of these entities, including tracking changes and persisting them to the database.

Entity Properties

Entity properties expose the data contained within an entity. These properties can be simple types (like string, int, DateTime) or complex types. The primary key property is crucial for uniquely identifying an entity instance.


public class Product
{
    public int ProductId { get; set; } // Primary Key
    public string Name { get; set; }
    public decimal Price { get; set; }
    public DateTime DateAdded { get; set; }
}
            

Creating and Attaching Entities

When you retrieve data using Entity Framework, entities are automatically created and tracked by the DbContext. You can also create new entities manually and attach them to the context.

Creating a New Entity

Instantiate your entity class like any other .NET object.


var newProduct = new Product
{
    Name = "Super Widget",
    Price = 19.99m,
    DateAdded = DateTime.Now
};
            

Attaching an Entity to the Context

To inform the DbContext about a new or existing entity that it should track, you use the Add or Attach methods.

Adding a New Entity

Use Add for new entities that you intend to insert into the database.


using (var context = new MyDbContext())
{
    var newProduct = new Product { Name = "Awesome Gadget", Price = 29.95m };
    context.Products.Add(newProduct); // Adds to the context with Added state
    context.SaveChanges();
}
            

Attaching an Existing Entity

Use Attach for entities that already exist in the database but are not currently tracked by the context. This is common when working with disconnected scenarios.


// Assume 'productFromAnotherContext' was retrieved or created elsewhere
var productFromAnotherContext = new Product { ProductId = 1, Name = "Updated Name" };

using (var context = new MyDbContext())
{
    context.Products.Attach(productFromAnotherContext); // Attaches with Unchanged state
    context.Entry(productFromAnotherContext).State = EntityState.Modified; // Mark as modified if needed
    context.SaveChanges();
}
            

Entity States

Entity Framework tracks the state of each entity within the context. Common states include:

Accessing and Modifying Entity State

You can access the state of an entity using the Entry method of the DbContext.


using (var context = new MyDbContext())
{
    var product = context.Products.Find(1); // Retrieves product with ID 1

    if (product != null)
    {
        Console.WriteLine($"Initial state: {context.Entry(product).State}"); // Output: Unchanged

        product.Price = 15.50m;
        context.SaveChanges();
        Console.WriteLine($"State after modification: {context.Entry(product).State}"); // Output: Modified
    }
}
            

Relationships between Entities

Entities can have relationships with each other, representing foreign key constraints in the database. Entity Framework supports one-to-one, one-to-many, and many-to-many relationships.

Navigation Properties

Navigation properties allow you to navigate between related entities. For example, a Category entity might have a collection of Product entities.


public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; } // Navigation property
}

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int CategoryId { get; set; } // Foreign key
    public virtual Category Category { get; set; } // Navigation property
}
            

Working with Related Entities

Entity Framework makes it easy to work with related data. When you load an entity, you can often automatically load its related entities using techniques like eager loading, lazy loading, or explicit loading.

Important: Ensure your entity classes are decorated with virtual properties for navigation properties if you intend to use lazy loading.

Consider this example of adding a product to a category:


using (var context = new MyDbContext())
{
    var category = context.Categories.Find(1);
    var newProduct = new Product { Name = "New Product", Price = 50.00m };

    if (category != null)
    {
        // Option 1: Assign directly through navigation property
        newProduct.Category = category;
        category.Products.Add(newProduct); // If Category.Products is loaded and includes newProduct

        // Option 2: Assign foreign key and then attach/add
        // newProduct.CategoryId = category.CategoryId;
        // context.Products.Add(newProduct);

        context.SaveChanges();
    }
}
            

Entity Framework Core vs. EF6

Entity Framework Core is the latest generation of Entity Framework, a cross-platform, open-source, and extensible version of Entity Framework. While many concepts are similar, there are differences in APIs and features compared to the older Entity Framework 6.

For the most up-to-date information and best practices, always refer to the latest official Entity Framework Core documentation.

This section provides a foundational understanding of working with entities in Entity Framework. Explore the other sections for details on querying, saving changes, and advanced scenarios.