双重外键生成 [英] Double foreign key generation

查看:162
本文介绍了双重外键生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是此问题的后续问题,我曾经在此类似问题。但是现在,这是通过默认的外键约定来解决的。

This is a followup-question of this question, where i had a similar problem. But this is solved now by default foreign key convention.

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

My problem now is (in short), that my migrations generates

int ReferencedEntityID;
int ReferencedEntity_ReferencedEntityID;

int ReferencedEntityID; int ReferencedEntity_ReferencedEntityID;

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

where one is an integer property in my model and the other one is a virtual property.

我的迁移产生了这一点:

My migrations generates this:

"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(),
                })

如您所见,Client&文章被引用两次。

As you can see, Client & Article are referenced twice.

这是我的模型

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()

Here is my 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);
        }

我要做什么,创建两者:

What do i have to do, to create them both:


  • 必需

  • 我的数据库模式中的一个属性(应该)

推荐答案

甚至推荐使用原始的FK属性(如 ArticleId )伴随着真实参考。在EF中,这被称为外键关联,而不是独立关联,只有一个引用(如 Article.Company )。

It is OK, even recommended, to have primitive FK properties (like ArticleId) accompanying the "real" references. In EF this is called a foreign key association as opposed to an independent association where there is only a reference (like Article.Company).

所以你可以让你的模型保持原样。你只需要指定外键。

So you can keep your model the way it is. You just have to specify the foreign keys.

我在上一个问题的模型中尝试了几个类,这样就产生了所需的结果:

I tried with a few classes in the model of your previous question and this produced the desired results:

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字段。我不知道为什么。

Note that I turned around the definitions because when I did it your way, but with HasForeignKey it still duplicated the FK fields. I'm not sure why.

这篇关于双重外键生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆