双重外键生成 [英] Double foreign key generation
问题描述
这是此问题的后续问题,我曾经在此类似问题。但是现在,这是通过默认的外键约定来解决的。
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屋!