Aida-Hagh / EF-Core

Learn EF Core
1 stars 0 forks source link

Example : Fluent API configuration for User #27

Open Aida-Hagh opened 3 months ago

Aida-Hagh commented 3 months ago

تنظیمات Fluent API برای کلاس User :

public class User : AggregateRoot {

public string Name { get; private set; }
public string Family { get; private set; }
public string PhoneNumber { get; private set; }
public string Email { get; private set; }
public string Password { get; private set; }
public string AvatarName { get; set; }
public bool IsActive { get; set; }
public Gender Gender { get; private set; }
public List<UserRole> Roles { get; }
public List<Wallet> Wallets { get; }
public List<UserAddress> Addresses { get; }
public List<UserToken> Tokens { get; }

}

در این مثال میخواهیم تنظیمات مربوط به مدل رو در کلاس جداگانه ای قرار بدیم وبعد در کلاس context در متد OnModelCreating فراخوانی کنیم که این باعث سازماندهی بهتر و نگهداری آسان تنظیمات مدل ها میشود.البته در این مثال User اگریگیت روت(AggregateRoot) هست و UserAddress ،UserToken ،Wallet، UserRole چایلدهاش هستند. طبق مراحل زیر انجام میدیم:

  1. یک کلاس تنظیمات برای User ایجاد میکنیم که از IEntityTypeConfiguration پیروی کند.

internal class UserConfiguration : IEntityTypeConfiguration {

public void Configure(EntityTypeBuilder<User> builder)
{
    builder.ToTable("Users", "user");
    builder.HasIndex(u => u.Email).IsUnique();
    builder.HasIndex(u => u.PhoneNumber).IsUnique();

    builder.Property(u => u.Name).IsRequired(false).HasMaxLength(80);
    builder.Property(u => u.Family).IsRequired(false).HasMaxLength(80);
    builder.Property(b => b.Email).IsRequired(false).HasMaxLength(256);
    builder.Property(b => b.PhoneNumber).IsRequired().HasMaxLength(11);
    builder.Property(b => b.Password).IsRequired().HasMaxLength(50);

    builder.OwnsMany(b => b.Tokens, option =>  //یک به چند
    {
        option.ToTable("Tokens", "user");
        option.HasKey(b => b.Id);

        option.Property(b => b.HashJwtToken)
            .IsRequired()
            .HasMaxLength(250);

        option.Property(b => b.HashRefreshToken)
            .IsRequired()
            .HasMaxLength(250);

        option.Property(b => b.Device)
            .IsRequired()
            .HasMaxLength(100);
    });

    builder.OwnsMany(b => b.Addresses, option =>     //یک به چند
    {
        option.HasIndex(b => b.UserId);
        option.ToTable("Addresses", "user");

        option.Property(b => b.Province)
             .IsRequired().HasMaxLength(100);

        option.Property(b => b.City)
            .IsRequired().HasMaxLength(100);

        option.Property(b => b.Name)
           .IsRequired().HasMaxLength(50);

        option.Property(b => b.Family)
            .IsRequired().HasMaxLength(50);

        option.Property(b => b.NationalCode)
            .IsRequired().HasMaxLength(10);

        option.Property(b => b.PostalCode)
            .IsRequired().HasMaxLength(20);

        option.OwnsOne(c => c.PhoneNumber, config =>     // است ValueObject شماره در یوزر آدرس
        {
            config.Property(b => b.Value)
                .HasColumnName("PhoneNumber")
                .IsRequired().HasMaxLength(11);
        });
    });

    builder.OwnsMany(b => b.Wallets, option =>      //یک به چند
    {
        option.ToTable("Wallets", "user");
        option.HasIndex(b => b.UserId);

        option.Property(b => b.Description)
            .IsRequired(false)
            .HasMaxLength(500);
    });

    builder.OwnsMany(b => b.Roles, option =>        //یک به چند
    {
        option.ToTable("Roles", "user");
        option.HasIndex(b => b.UserId);
    });
}

}

2.در کلاس ShopContext، می‌توانیم از متد ApplyConfigurationsFromAssembly برای فراخوانی تمام تنظیمات پیکربندی مدل‌ها از یک اسمبلی خاص استفاده کنیم.

public class ShopContext : DbContext {

public ShopContext(DbContextOptions<ShopContext> options):base(options)  
{
}
public DbSet<User> Users { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{     // نشه تا کارایی بالا برهTrack کد زیر باعث میشه هر کوئری که روی این کانتکس اجرا میشه  
    optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
    base.OnConfiguring(optionsBuilder);
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyConfigurationsFromAssembly(typeof(ShopContext).Assembly);
    base.OnModelCreating(modelBuilder);
}

}