EFEF Core Handbook

REFERANS

Data Annotations Hızlı Referans

Fluent API yerine attribute bazlı yapılandırma. Basit senaryolarda hızlıdır ama Fluent API kadar güçlü değildir (composite index, owned entity gibi şeyler attribute ile yapılamaz).

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class Product
{
    [Key]
    public int Id { get; set; }

    [Required]
    [MaxLength(200)]
    [Column("ProductName")]
    public string Name { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal Price { get; set; }

    [StringLength(500, MinimumLength = 10)]
    public string Description { get; set; }

    [Range(0, 9999)]
    public int Stock { get; set; }

    [NotMapped]
    public string ComputedField => $"{Name} - {Price:C}";

    [Timestamp]
    public byte[] RowVersion { get; set; }

    [ConcurrencyCheck]
    public string Slug { get; set; }

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

    [InverseProperty("Products")]
    public ICollection<Tag> Tags { get; set; }
}

[Table("Categories", Schema = "catalog")]
[Index(nameof(Code), IsUnique = true)]
public class Category
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Unicode(false)]
    [MaxLength(50)]
    public string Code { get; set; }
}

Data Annotation → Fluent API Eşleştirmesi

Data Annotation Fluent API Karşılığı
[Key] .HasKey(p => p.Id)
[Required] .Property(p => p.X).IsRequired()
[MaxLength(n)] .HasMaxLength(n)
[StringLength(n)] .HasMaxLength(n)
[Column("name")] .HasColumnName("name")
[Column(TypeName="t")] .HasColumnType("t")
[NotMapped] .Ignore(p => p.X)
[Timestamp] .IsRowVersion()
[ConcurrencyCheck] .IsConcurrencyToken()
[Table("T", Schema="S")] .ToTable("T", "S")
[Index(nameof(X))] .HasIndex(p => p.X)
[Index(..., IsUnique=true)] .HasIndex(p => p.X).IsUnique()
[ForeignKey("FkId")] .HasForeignKey(p => p.FkId)
[InverseProperty("Nav")] .WithMany(x => x.Nav) / .WithOne(...)
[Owned] .OwnsOne(...)
[DatabaseGenerated(Identity)] .ValueGeneratedOnAdd()
[DatabaseGenerated(Computed)] .ValueGeneratedOnAddOrUpdate()
[DatabaseGenerated(None)] .ValueGeneratedNever()
[Unicode(false)] .IsUnicode(false)
[Precision(18,2)] .HasPrecision(18, 2)
[Comment("...")] .HasComment("...")
[DeleteBehavior(...)] .OnDelete(DeleteBehavior.X)

Fluent API vs Data Annotations?

  • Fluent API daha güçlü (her şeyi yapabilir), clean architecture'da tercih edilir
  • Data Annotations hızlı prototip için uygun, validation ile ortak kullanılır
  • İkisi çakışırsa Fluent API kazanır