EF Core 3 Scaffolding (Database first) does not generate Primary Key Fluent API

.net .net-core c# ef-core-3.0 entity-framework-core

Question

I have scoffeled all my models for the project from an existing database, using EntityFramework's Scaffold-DbContext command.

EntityFramework did a perfect job in creating all of the models mapped to a table and generating the Fluent API fonfiguration code.

From what I have noticed, the Fluent API code is missing the configuration of the Primary Key field, although it has added the propery to the generated model.

Here is an example of one of my generated classes and its corresponding Fluent API code:

public partial class Account
{
    public int AccountId { get; set; } //Primary Key
    public int CompanyId { get; set; }
    public int CompanyAccountTypeId { get; set; }
    public int? CompanyAccountGroupId { get; set; }
    public int? RegionId { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string IncludeEscalationEmail { get; set; }
    public decimal? Gpslat { get; set; }
    public decimal? Gpslong { get; set; }
    public string Telephone { get; set; }
    public string Vatnumber { get; set; }
    public bool AutoReceive { get; set; }
    public bool AutoIssue { get; set; }
    public bool? IsBillableToAccount { get; set; }
    public DateTime? BillingStart { get; set; }
    public bool? IsEquipmentDepot { get; set; }
    public bool? IsShiftAttendanceEnabled { get; set; }
    public int? ShiftMinHoursForLunchDeduction { get; set; }
    public TimeSpan? NightShiftStart { get; set; }
    public TimeSpan? NightShiftEnd { get; set; }
    public int? ShiftStartDayOfMonth { get; set; }
    public TimeSpan? OperatingHoursStart { get; set; }
    public TimeSpan? OperatingHoursEnd { get; set; }
    public int? LoadBays { get; set; }
    public int? LoadInterval { get; set; }
    public int? ArrivalInterval { get; set; }
    public TimeSpan? OverrideStockTakeCloseBalanceTime { get; set; }
    public bool? TempIgnoreVendorIssueViaSap { get; set; }
    public bool Archived { get; set; }
    public DateTime CreatedDate { get; set; }
    public int CreatedByPersonId { get; set; }
    public DateTime UpdatedDate { get; set; }
    public int UpdatedByPersonId { get; set; }

    public virtual Company Company { get; set; }
    public virtual CompanyAccountGroup CompanyAccountGroup { get; set; }
    public virtual CompanyAccountType CompanyAccountType { get; set; }
    public virtual Region Region { get; set; }
    public virtual ICollection<AccountBalance> AccountBalance { get; set; }
    public virtual ICollection<AccountContact> AccountContact { get; set; }
    public virtual ICollection<AccountEquipment> AccountEquipment { get; set; }
    public virtual ICollection<AccountHrlookup> AccountHrlookup { get; set; }
    public virtual ICollection<AccountPickVolumeDefault> AccountPickVolumeDefaultAccount { get; set; }
    public virtual ICollection<AccountPickVolumeDefault> AccountPickVolumeDefaultPartnerAccount { get; set; }
    public virtual ICollection<AccountPickVolumeDetail> AccountPickVolumeDetail { get; set; }
    public virtual ICollection<AccountPickVolumePartner> AccountPickVolumePartner { get; set; }
    public virtual ICollection<AppUserAccount> AppUserAccount { get; set; }
    public virtual ICollection<BiometricTerminal> BiometricTerminal { get; set; }
    public virtual ICollection<CompanyVendorAccount> CompanyVendorAccount { get; set; }
    public virtual ICollection<EquipmentCheck> EquipmentCheckAccount { get; set; }
    public virtual ICollection<EquipmentCheck> EquipmentCheckAccountMaintenance { get; set; }
    public virtual ICollection<GantryTransfer> GantryTransferCreditAccount { get; set; }
    public virtual ICollection<GantryTransfer> GantryTransferDebitAccount { get; set; }
    public virtual ICollection<Order> OrderDepotAccount { get; set; }
    public virtual ICollection<Order> OrderPrimaryAccount { get; set; }
    public virtual ICollection<Rfequipment> Rfequipment { get; set; }
    public virtual ICollection<RfmoveTransaction> RfmoveTransactionPartnerAccount { get; set; }
    public virtual ICollection<RfmoveTransaction> RfmoveTransactionPrimaryAccount { get; set; }
    public virtual ICollection<ShiftCalendar> ShiftCalendar { get; set; }
    public virtual ICollection<ShiftSchedule> ShiftSchedule { get; set; }
    public virtual ICollection<ShiftTeam> ShiftTeam { get; set; }
    public virtual ICollection<TransferDeviance> TransferDevianceIssueAccount { get; set; }
    public virtual ICollection<TransferDeviance> TransferDevianceIssuePartnerAccount { get; set; }
    public virtual ICollection<TransferDeviance> TransferDevianceReceiptAccount { get; set; }
    public virtual ICollection<TransferDeviance> TransferDevianceReceiptPartnerAccount { get; set; }
    public virtual ICollection<TransferJournal> TransferJournalCreditAccount { get; set; }
    public virtual ICollection<TransferJournal> TransferJournalDebitAccount { get; set; }
    public virtual ICollection<Transfer> TransferPartnerAccount { get; set; }
    public virtual ICollection<Transfer> TransferPrimaryAccount { get; set; }
    public virtual ICollection<VehicleCheckIn> VehicleCheckIn { get; set; }
    public virtual ICollection<XAppUserAccountAccess> XAppUserAccountAccess { get; set; }
}

Here is the Fluent API:

builder.HasIndex(e => new { e.AccountId, e.CompanyAccountTypeId, e.Name, e.Code, e.CompanyId })
                .HasName("IX_AccountCompanyType");

        builder.HasIndex(e => new { e.Archived, e.AccountId, e.UpdatedDate, e.CompanyId, e.CompanyAccountTypeId, e.CompanyAccountGroupId, e.RegionId })
            .HasName("IX_AppUserAccountAccess");

        builder.HasIndex(e => new { e.AccountId, e.CompanyId, e.CompanyAccountGroupId, e.RegionId, e.Name, e.Gpslong, e.BillingStart, e.Code, e.Address, e.Email, e.IncludeEscalationEmail, e.Gpslat, e.ArrivalInterval, e.Telephone, e.Vatnumber, e.AutoReceive, e.AutoIssue, e.IsBillableToAccount, e.UpdatedDate, e.IsEquipmentDepot, e.OperatingHoursStart, e.OperatingHoursEnd, e.LoadBays, e.LoadInterval, e.UpdatedByPersonId, e.OverrideStockTakeCloseBalanceTime, e.TempIgnoreVendorIssueViaSap, e.Archived, e.CreatedDate, e.CreatedByPersonId, e.CompanyAccountTypeId })
            .HasName("IX_vAccount");

        builder.Property(e => e.Address)
            .HasMaxLength(500)
            .IsUnicode(false);

        builder.Property(e => e.BillingStart).HasColumnType("date");

        builder.Property(e => e.Code)
            .HasMaxLength(50)
            .IsUnicode(false);

        builder.Property(e => e.CreatedByPersonId).HasColumnName("CreatedBy_PersonId");

        builder.Property(e => e.CreatedDate).HasColumnType("datetime");

        builder.Property(e => e.Email)
            .HasMaxLength(200)
            .IsUnicode(false);

        builder.Property(e => e.Gpslat)
            .HasColumnName("GPSLat")
            .HasColumnType("decimal(18, 6)");

        builder.Property(e => e.Gpslong)
            .HasColumnName("GPSLong")
            .HasColumnType("decimal(18, 6)");

        builder.Property(e => e.IncludeEscalationEmail)
            .HasMaxLength(500)
            .IsUnicode(false);

        builder.Property(e => e.Name)
            .IsRequired()
            .HasMaxLength(255)
            .IsUnicode(false);

        builder.Property(e => e.Telephone)
            .HasMaxLength(20)
            .IsUnicode(false);

        builder.Property(e => e.TempIgnoreVendorIssueViaSap).HasColumnName("temp_IgnoreVendorIssueViaSAP");

        builder.Property(e => e.UpdatedByPersonId).HasColumnName("UpdatedBy_PersonId");

        builder.Property(e => e.UpdatedDate).HasColumnType("datetime");

        builder.Property(e => e.Vatnumber)
            .HasColumnName("VATNumber")
            .HasMaxLength(50)
            .IsUnicode(false);

        builder.HasOne(d => d.CompanyAccountGroup)
            .WithMany(p => p.Account)
            .HasForeignKey(d => d.CompanyAccountGroupId)
            .HasConstraintName("FK_Account_CompanyAccountGroup");

        builder.HasOne(d => d.CompanyAccountType)
            .WithMany(p => p.Account)
            .HasForeignKey(d => d.CompanyAccountTypeId)
            .OnDelete(DeleteBehavior.ClientSetNull)
            .HasConstraintName("FK_Account_CompanyAccountType");

        builder.HasOne(d => d.Company)
            .WithMany(p => p.Account)
            .HasForeignKey(d => d.CompanyId)
            .OnDelete(DeleteBehavior.ClientSetNull)
            .HasConstraintName("FK_Account_Company");

        builder.HasOne(d => d.Region)
            .WithMany(p => p.Account)
            .HasForeignKey(d => d.RegionId)
            .HasConstraintName("FK_Account_Region");

As you can see, my model has the Primary Key field named AccountId. Why does the mapping for this not get added in the Fluent API code?

1
0
11/13/2019 6:44:31 AM

Popular Answer

It's not being added, because it's a convention that this property is the primary key.

From Conventions in Entity Framework Core:

If a property is named ID or <entity name>ID (not case-sensitive), it will be configured as the primary key. Entity Framework Core will prefer ID over <entity name>ID in the event that a class contains both.

0
11/13/2019 7:31:42 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow