【问题标题】:EF Core 3 Scaffolding (Database first) does not generate Primary Key Fluent APIEF Core 3 Scaffolding(数据库优先)不生成主键 Fluent API
【发布时间】:2019-11-13 06:44:31
【问题描述】:

我已经使用 EntityFramework 的 Scaffold-DbContext 命令从现有数据库中嘲笑了我的所有项目模型。

EntityFramework 在创建映射到表的所有模型和生成Fluent API 配置代码方面做得非常出色。

据我所知,Fluent API 代码缺少Primary Key 字段的配置,尽管它已将属性添加到生成的模型中。

这是我生成的一个类及其对应的Fluent API 代码的示例:

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; }
}

这是 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");

如您所见,我的模型具有名为 AccountId 的主键字段。为什么 Fluent API 代码中没有添加此映射?

【问题讨论】:

  • 您是否尝试过使用 AccountId 的 [Key]?

标签: c# .net .net-core entity-framework-core ef-core-3.0


【解决方案1】:

它没有被添加,因为这个属性是主键的约定。

来自Conventions in Entity Framework Core

如果一个属性被命名为ID&lt;entity name&gt;ID(不区分大小写),它将被配置为主键。如果一个类同时包含两者,Entity Framework Core 将更喜欢 ID 而不是 &lt;entity name&gt;ID

【讨论】:

    猜你喜欢
    • 2018-09-05
    • 2020-05-22
    • 2019-06-05
    • 2012-03-19
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多