< Summary

Information
Class: OzonRepositories.Context.Identity.OzonIdentityOrderContext
Assembly: OzonRepositories
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonRepositories/Context/Identity/OzonIdentityOrderContext.cs
Line coverage
100%
Covered lines: 35
Uncovered lines: 0
Coverable lines: 35
Total lines: 72
Line coverage: 100%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_AccessProfiles()100%11100%
OnModelCreating(...)100%22100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonRepositories/Context/Identity/OzonIdentityOrderContext.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Identity;
 2using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
 3using Microsoft.EntityFrameworkCore;
 4using OzonDomains.Models.AccessControl;
 5
 6namespace OzonRepositories.Context.Identity
 7{
 8    public class OzonIdentityOrderContext : IdentityDbContext<CustomIdentityUser>
 9    {
 410        public OzonIdentityOrderContext(DbContextOptions<OzonIdentityOrderContext> options) : base(options) { }
 11
 212        public DbSet<AccessProfile> AccessProfiles { get; set; }
 13
 14        protected override void OnModelCreating(ModelBuilder builder)
 15        {
 116            base.OnModelCreating(builder);
 17
 18            // AddEntityFrameworkStores в DI выставляет IdentityOptions.Stores.MaxLengthForKeys = 128,
 19            // и боевые таблицы созданы именно с этой длиной. Design-time factory поднимает
 20            // контекст без DI, где значение по умолчанию — 0 (то есть varchar(255)).
 21            // Фиксируем длины явно, чтобы модель не зависела от способа сборки контекста.
 122            builder.Entity<IdentityUserLogin<string>>(e =>
 123            {
 124                e.Property(x => x.LoginProvider).HasMaxLength(128);
 125                e.Property(x => x.ProviderKey).HasMaxLength(128);
 226            });
 127            builder.Entity<IdentityUserToken<string>>(e =>
 128            {
 129                e.Property(x => x.LoginProvider).HasMaxLength(128);
 130                e.Property(x => x.Name).HasMaxLength(128);
 231            });
 32
 33            // AccessProfile тянет за собой DataScopeSet/DataScopeSetItem и join-таблицу.
 34            // Без явных имён EF выводил их в единственном числе (DataScopeSet,
 35            // DataScopeSetItem, AccessProfileDataScopeSet) — таких таблиц в БД нет,
 36            // и модель этого контекста расходилась с ApplicationDbContext.
 37            //
 38            // Владелец этих четырёх таблиц — ApplicationDbContext, он их и создаёт.
 39            // ExcludeFromMigrations не даёт второму набору миграций создать их повторно:
 40            // оба контекста работают с одной и той же базой.
 141            builder.Entity<AccessProfile>()
 242                .ToTable("AccessProfiles", t => t.ExcludeFromMigrations());
 143            builder.Entity<DataScopeSet>()
 244                .ToTable("DataScopeSets", t => t.ExcludeFromMigrations());
 145            builder.Entity<DataScopeSetItem>()
 246                .ToTable("DataScopeSetItems", t => t.ExcludeFromMigrations());
 147            builder.Entity<AccessProfile>()
 148                .HasMany(ap => ap.DataScopeSets)
 149                .WithMany(ds => ds.AccessProfiles)
 350                .UsingEntity(j => j.ToTable("AccessProfileDataScopeSets", t => t.ExcludeFromMigrations()));
 51
 52            // В production-базе AspNetUsers встречаются legacy-строки с пустым Discriminator.
 53            // IsComplete(false) добавляет фильтрацию по известным типам и не даёт EF падать
 54            // при чтении строк с неизвестным/пустым значением дискриминатора.
 155            builder.Entity<CustomIdentityUser>()
 156                .HasDiscriminator<string>("Discriminator")
 157                .IsComplete(false)
 158                .HasValue<CustomIdentityUser>(nameof(CustomIdentityUser));
 59
 160            builder.Entity<CustomIdentityUser>()
 161                .HasOne(u => u.AccessProfile)
 162                .WithMany()
 163                .HasForeignKey(u => u.AccessProfileId)
 164                .OnDelete(DeleteBehavior.SetNull);
 65
 166            if (ApplicationDbContext.IsMySqlProvider(Database.ProviderName))
 67            {
 168                ProdSchemaAlignment.Apply(builder);
 69            }
 170        }
 71    }
 72}