EF Core - Data Annotations Configuration

Data Annotations in Entity Framework Core (EF Core) provide a way to configure your data models using attributes. They offer a convenient and declarative approach to define constraints, relationships, and mappings directly in your entity classes. This tutorial covers the various data annotations you can use in EF Core to configure your data models effectively.


1. Key Attribute

The [Key] attribute is used to designate a property as the primary key of an entity. It's particularly useful when the primary key property doesn't follow EF Core's naming conventions.

        
            
public class Product
{
    [Key]
    public int ProductId { get; set; }
    public string Name { get; set; }
}
        
    

In this example, the ProductId property is marked as the primary key.


2. Required Attribute

The [Required] attribute is used to enforce that a property must have a value. It translates to a NOT NULL constraint in the database.

        
            
public class Product
{
    public int ProductId { get; set; }
    
    [Required]
    public string Name { get; set; }
}
        
    

This example ensures that the Name property cannot be null.


3. String Length Attribute

The [StringLength] attribute is used to specify the maximum length of a string property.

        
            
public class Product
{
    public int ProductId { get; set; }

    [StringLength(100)]
    public string Name { get; set; }
}
        
    

This example restricts the Name property to a maximum length of 100 characters.


4. MaxLength Attribute

The [MaxLength] attribute is used to specify the maximum length for array-like properties such as strings and byte arrays.

        
            
public class Product
{
    public int ProductId { get; set; }

    [MaxLength(200)]
    public string Description { get; set; }
}
        
    

This example sets a maximum length of 200 characters for the Description property.


5. Column Attribute

The [Column] attribute is used to specify the name of the database column that a property maps to.

        
            
public class Product
{
    public int ProductId { get; set; }

    [Column("Product_Name")]
    public string Name { get; set; }
}
        
    

In this example, the ProductName property is mapped to the Product_Name column.


6. Table Attribute

The [Table] attribute is used to specify the database table name that an entity maps to.

        
            
[Table("tbl_Products")]
public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
}
        
    

This example maps the Product entity to the tbl_Products table.


7. ForeignKey Attribute

The [ForeignKey] attribute is used to specify the foreign key property for a navigation property.

        
            
public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }

    [ForeignKey("CategoryId")]
    public Category Category { get; set; }
    public int CategoryId { get; set; }
}
        
    

In this example, the CategoryId property is the foreign key for the Category navigation property.


8. InverseProperty Attribute

The [InverseProperty] attribute is used to configure the inverse navigation property for a relationship.

        
            
public class Order
{
    public int OrderId { get; set; }
    public List<OrderItem> OrderItems { get; set; }

    [InverseProperty("Order")]
    public OrderDetails OrderDetails { get; set; }
}

public class OrderItem
{
    public int OrderItemId { get; set; }
    public int OrderId { get; set; }

    [InverseProperty("OrderItems")]
    public Order Order { get; set; }
}
        
    

This example demonstrates how to configure inverse navigation properties between Order and OrderItem.


9. NotMapped Attribute

The [NotMapped] attribute is used to exclude a property from being mapped to a database column.

        
            
public class Product
{
    public int ProductId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [NotMapped]
    public string FullName => $"{FirstName} {LastName}";
}
        
    

In this example, the FullName property is excluded from the database mapping.


10. Index Attribute

The [Index] attribute is used to specify an index on one or more columns.

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

    [Index(IsUnique = true)]
    public string Email { get; set; }
}
        
    

This example creates an index on the Email property.


11. Computed Column Attribute

The [DatabaseGenerated] attribute with DatabaseGeneratedOption.Computed is used to indicate that a property is computed by the database.

        
            
public class Order
{
    public int OrderId { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public decimal TotalPrice { get; set; }
}
        
    

In this example, the TotalPrice property is computed by the database.


12. Best Practices for Data Annotations

Here are some best practices for using data annotations in EF Core:


Summary

Data annotations provide a simple and effective way to configure your EF Core models. They allow you to define constraints, relationships, and mappings directly in your entity classes. By following best practices and combining data annotations with the Fluent API when needed, you can create clean and maintainable data models for your applications.