MSDN Documentation

.NET Data Access / Entity Framework

Working with Entities

Working with entities in Entity Framework (EF) involves understanding how EF represents your data and how you can interact with it. Entities are essentially .NET objects that map to tables in your database. EF provides a rich set of features to create, read, update, and delete (CRUD) these entities seamlessly.

Entity States

Each entity instance within an EF context has a specific state. This state helps EF track changes made to the entity. The common states are:

Tracking Changes

An DbContext instance tracks entities that are retrieved from the database or added to the context. This tracking is crucial for detecting changes and generating the appropriate SQL commands for updates and inserts.

You can explicitly set the state of an entity using the Entry() method of your DbContext:


var product = new Product { Id = 1, Name = "Old Name" };
context.Entry(product).State = EntityState.Modified;
            

CRUD Operations

Creating Entities (Adding)

To add a new entity, create an instance of your entity class and add it to the appropriate DbSet on your DbContext.


var newProduct = new Product
{
    Name = "New Gadget",
    Price = 99.99m
};
context.Products.Add(newProduct);
context.SaveChanges(); // Inserts the new product into the database
            

Reading Entities (Querying)

Querying entities is typically done using LINQ to Entities. The DbContext translates your LINQ queries into SQL.


// Get all products
var allProducts = context.Products.ToList();

// Get a specific product by ID
var productById = context.Products.Find(1);

// Filter products
var expensiveProducts = context.Products.Where(p => p.Price > 50).ToList();
            

Updating Entities

When you retrieve an entity from the context, EF starts tracking it. Modifying its properties directly will mark it as Modified automatically.


var productToUpdate = context.Products.Find(2);
if (productToUpdate != null)
{
    productToUpdate.Name = "Updated Widget";
    productToUpdate.Price = 75.50m;
    context.SaveChanges(); // Updates the product in the database
}
            

If an entity is detached, you need to reattach it and mark it as modified:


var detachedProduct = new Product { Id = 3, Name = "Modified Name" };
context.Products.Attach(detachedProduct);
context.Entry(detachedProduct).State = EntityState.Modified;
context.SaveChanges();
            

Deleting Entities

To delete an entity, retrieve it from the context and then call the Remove() method on the DbSet.


var productToDelete = context.Products.Find(4);
if (productToDelete != null)
{
    context.Products.Remove(productToDelete);
    context.SaveChanges(); // Deletes the product from the database
}
            
Important: Always ensure that you call SaveChanges() on the DbContext to persist your changes to the database. If an exception occurs during SaveChanges(), the entire transaction will be rolled back.

Concurrency Handling

Concurrency conflicts can occur when multiple users or processes try to modify the same data simultaneously. Entity Framework provides mechanisms to handle these conflicts.

To implement optimistic concurrency, you can use row versioning (e.g., a timestamp column) or check all concurrency tokens. EF automatically detects and handles this for properties marked with the [Timestamp] attribute or using the IsRowVersion() configuration.

Managing State with Change Tracking Proxies

By default, EF creates proxy classes for your entities. These proxies automatically update the entity's state when properties are changed, simplifying change tracking.


// Assuming Change Tracking Proxies are enabled
var product = context.Products.Find(5);
product.Price = 120.00m; // EF automatically marks the product as Modified
context.SaveChanges();