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:
- Added: The entity is new and will be inserted into the database.
- Unchanged: The entity has been retrieved from the database and has not been modified.
- Modified: The entity has been retrieved and one or more of its properties have been changed.
- Deleted: The entity will be deleted from the database.
- Detached: The entity is not tracked by the context.
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.
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.