Skip to content

Settings.UseDataAnnotations

Simon Hughes edited this page Aug 30, 2026 · 1 revision

Settings.UseDataAnnotations

Adds [Key], [Required], [MaxLength] and friends to the generated properties, alongside the Fluent API configuration.

Type bool
Default false
Applies to EF 6 and EF Core
Databases All
In Database.tt? Yes

What it does

EF can be told about a model two ways: data annotations, which are attributes on the properties, and the Fluent API, which is the builder.Property(...) code in the configuration class. This generator always writes the Fluent API. This setting adds the annotations as well.

Turning it on gives you, automatically:

Situation Attribute
Primary key column [Key, Column(Order = n)]
Non-nullable column [Required], or [Required(AllowEmptyStrings = true)] for a string
String with a length [MaxLength(n)] and [StringLength(n)]
nvarchar(max) [MaxLength] with no argument
rowversion / timestamp [Timestamp, ConcurrencyCheck]
Every column [Display(Name = "...")], from the humanised column name
SQL Server 2025 vector [Column(TypeName = "vector(n)")]

System.ComponentModel.DataAnnotations and .Schema are added to the using list for you.

Example

Settings.UseDataAnnotations = false (default)

    // Product
    public class Product
    {
        public int ProductId { get; set; } // ProductId (Primary key)
        public string ProductName { get; set; } // ProductName (length: 100)
        public decimal UnitPrice { get; set; } // UnitPrice
        public string Notes { get; set; } // Notes
        public int CategoryId { get; set; } // CategoryId
        public string DisplayLabel { get; private set; } // DisplayLabel (length: 150)

        // Foreign keys

        /// <summary>
        /// Parent Category pointed by [Product].([CategoryId]) (FK_Product_Category)
        /// </summary>
        public Category Category { get; set; } // FK_Product_Category

        public Product()
        {
            UnitPrice = 0m;
        }
    }

Settings.UseDataAnnotations = true

    // Product
    [Table("Product", Schema = "dbo")]
    public class Product
    {
        [Key, Column(Order = 1)]
        [Required]
        [Display(Name = "Product ID")]
        public int ProductId { get; set; } // ProductId (Primary key)

        [MaxLength(100)]
        [StringLength(100)]
        [Required(AllowEmptyStrings = true)]
        [Display(Name = "Product name")]
        public string ProductName { get; set; } // ProductName (length: 100)

        [Required]
        [Display(Name = "Unit price")]
        [Precision(18, 2)]
        public decimal UnitPrice { get; set; } // UnitPrice

        [Display(Name = "Notes")]
        public string Notes { get; set; } // Notes

        [Required]
        [Display(Name = "Category ID")]
        public int CategoryId { get; set; } // CategoryId

        [MaxLength(150)]
        [StringLength(150)]
        [Display(Name = "Display label")]
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public string DisplayLabel { get; private set; } // DisplayLabel (length: 150)

        // Foreign keys

        /// <summary>
        /// Parent Category pointed by [Product].([CategoryId]) (FK_Product_Category)
        /// </summary>
        public Category Category { get; set; } // FK_Product_Category

        public Product()
        {
            UnitPrice = 0m;
        }
    }

The Fluent API configuration is unchanged in both cases - the annotations are additional, not a replacement.

When to use it

Turn it on when something other than EF reads the attributes. That is the real reason to want them:

  • ASP.NET model validation uses [Required], [MaxLength] and [StringLength] when binding a form or a request body to an entity.
  • Swagger / OpenAPI generators read them to describe request schemas.
  • UI frameworks - Blazor's DataAnnotationsValidator, older MVC scaffolding - work from them directly.
  • [Display(Name = ...)] gives every property a human-readable label, which those same UI frameworks use.

Leave it off if only EF reads your model. The Fluent API already says all of it, so the attributes are duplication, and duplication that can disagree with itself.

Gotchas

Do not validate an entity against these attributes and expect it to mean something. [Required] on a non-nullable column is a statement about the database, not about your business rules. A column that is NOT NULL with a default is [Required] here and perfectly fine to leave unset in your code.

[Required(AllowEmptyStrings = true)] is deliberate. A NOT NULL string column happily stores '', so [Required] without that argument would reject a value the database accepts. If you want empty strings rejected, that is a business rule and belongs in a validator, not in generated code.

Annotations and the Fluent API can disagree, and the Fluent API wins. If you edit an annotation by hand in a partial class, EF keeps using the generated builder.Property(...). Change the Fluent API too, or the model will not match what you read.

[Display] on every column is noisy. It is genuinely useful for UI scaffolding and pure clutter otherwise. To keep the rest without it, leave this setting off and call Settings.ApplyDataAnnotations(column) selectively from Settings.UpdateColumn.

Adding your own attributes does not need this setting. column.Attributes.Add("[MyAttribute]") in UpdateColumn works regardless. See Data Annotations.

See also

Clone this wiki locally