【问题标题】:Double foreign key generation双外键生成
【发布时间】:2013-01-23 21:47:56
【问题描述】:

这是this question 的后续问题,我遇到了类似的问题。但是现在默认外键约定解决了这个问题。

我现在的问题是(简而言之),我的迁移生成了

int ReferencedEntityID; int ReferencedEntity_ReferencedEntityID;

其中一个是我模型中的整数属性,另一个是虚拟属性。

我的迁移产生了这个:

"dbo.Contracts",
            c => new
                {
                    ContractId = c.Int(nullable: false, identity: true),
                    PricePerUnit = c.Double(nullable: false),
                    Unit = c.Int(nullable: false),
                    Currency = c.Int(nullable: false),
                    ClientId = c.Int(nullable: false),
                    CompanyId = c.Int(nullable: false),
                    ArticleId = c.Int(nullable: false),
                    Client_ClientId = c.Int(),
                    Article_ArticleId = c.Int(),
                })

如您所见,客户和文章被引用了两次。

这是我的模型

public class Client {
    public Client() { }

    [Key]
    public int ClientId { get; set; }
    public string Number { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string Memo { get; set; }
    public bool isMerchant { get; set; }

    public string Name
    {
        get
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }
    }

    public int? MerchantReferenceId { get; set; }
    public virtual Client MerchantReference { get; set; }
    [Required]
    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }
    public virtual ICollection<Contract> Contracts { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

public class Article {

    public Article() { }

    [Key]
    public int ArticleId { get; set; }
    [Required]
    public string Code { get; set; }
    public string Name { get; set; }
    public bool TrackStock { get; set; }
    public int CurrentStock { get; set; }
    public double? Price { get; set; }

    [Required]
    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }
    [Required]
    public int CategoryId { get; set; }
    public virtual Category Category { get; set; }

    public virtual ICollection<Contract> Contracts { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

public class Contract {

    public Contract() { }

    [Key]
    public int ContractId { get; set; }
    public double PricePerUnit { get; set; }
    public int Unit { get; set; }
    public int Currency { get; set; }

    [Required]
    public int ClientId { get; set; }
  //  [ForeignKey("ClientId")]
    public virtual Client Client { get; set; }

    [Required]
    public int CompanyId { get; set; }
    //[ForeignKey("CompanyID")]
    public virtual Company Company { get; set; }

    [Required]
    public int ArticleId { get; set; }
   // [ForeignKey("ArticleId")]
    public virtual Article Article { get; set; }

}

这是我的 OnModelCreating()

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
           // modelBuilder.Entity<Contract>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false);
            modelBuilder.Entity<Contract>().HasRequired(bm => bm.Article).WithMany().HasForeignKey(dl => dl.ArticleId).WillCascadeOnDelete(false);//.Map( dl => dl.MapKey("ArticleId"))
            modelBuilder.Entity<Contract>().HasRequired(bm => bm.Client).WithMany().HasForeignKey(dl => dl.ClientId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("ClientId"))
            modelBuilder.Entity<Article>().HasRequired(bm => bm.Company).WithMany().HasForeignKey(dl => dl.CompanyId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("CompanyId"))
            modelBuilder.Entity<Measurement>().HasRequired(bm => bm.Company).WithMany().HasForeignKey(dl => dl.CompanyId).WillCascadeOnDelete(false); //.Map(dl => dl.MapKey("CompanyId"))
            modelBuilder.Entity<Order>().HasRequired(bm => bm.Client).WithMany().HasForeignKey(dl => dl.ClientId).WillCascadeOnDelete(false); //.Map(dl => dl.MapKey("ClientId"))
            modelBuilder.Entity<Order>().HasRequired(bm => bm.Article).WithMany().HasForeignKey(dl => dl.ArticleId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("ArticleId"))
            modelBuilder.Entity<IncomingMeasurement>().HasRequired(bm => bm.client).WithMany().HasForeignKey(dl => dl.ClientId).WillCascadeOnDelete(false);//.Map(dl => dl.MapKey("ClientId"))
            modelBuilder.Entity<Client>().HasOptional(c => c.MerchantReference).WithMany().HasForeignKey(dl => dl.MerchantReferenceId); //.Map(dl => dl.MapKey("MerchantReferenceId"))

            //Required fields


            base.OnModelCreating(modelBuilder);
        }

我需要做什么来创建它们:

  • 必填
  • 在我的 db-schema 中的一个属性中(应该如此)

【问题讨论】:

    标签: c# ef-code-first entity entity-framework-5


    【解决方案1】:

    可以,甚至建议在“真实”引用中附带原始 FK 属性(如 ArticleId)。在 EF 中,这称为 外键关联,而不是只有引用的独立关联(如 Article.Company)。

    因此,您可以保持模型保持原样。您只需指定外键即可。

    我在你之前的问题的模型中尝试了几个类,这产生了预期的结果:

    modelBuilder.Entity<Article>().HasMany(a => a.Contracts)
        .WithRequired(c => c.Article)
        .HasForeignKey(c => c.ArticleID).WillCascadeOnDelete(false);
    modelBuilder.Entity<Client>().HasMany(c => c.Contracts)
        .WithRequired(c => c.Client)
        .HasForeignKey(c => c.ClientID).WillCascadeOnDelete(false);
    modelBuilder.Entity<Company>().HasMany(c => c.Articles)
        .WithRequired(a => a.Company)
        .HasForeignKey(c => c.CompanyID).WillCascadeOnDelete(false);
    

    请注意,我翻转了定义,因为当我按照您的方式进行操作时,但使用 HasForeignKey 它仍然重复了 FK 字段。我不知道为什么。

    【讨论】:

    • 太好了,解决了我的问题!我没有在我的模型构建器中引用实体。例如。我使用 .WithMany() 而不是 .WithMany(dl => dl.Clients) 并且生成了重复的 FK。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 2021-04-21
    • 1970-01-01
    相关资源
    最近更新 更多