[英]Understanding ForeignKey attribute in entity framework code first
有關背景信息,請參閱以下帖子:
我一直認為ForeignKey
用於顯示類中哪個屬性持有確定導航屬性的ForeignKey,例如
public class MemberDataSet
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int? DeferredDataId { get; set; }
[ForeignKey("DeferredDataId")]
public virtual DeferredData DeferredData { get; set; }
}
但是,我在鏈接的帖子上發現這是不對的,因為DeferredData的主鍵被稱為Id我實際需要:
public class MemberDataSet
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int? DeferredDataId { get; set; }
[ForeignKey("Id")]
public virtual DeferredData DeferredData { get; set; }
}
即ForeignKey
用於指向另一個類。
然后我繼續改變其他一些參考文獻:
public class MemberDataSet
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int? DeferredDataId { get; set; }
[ForeignKey("Id")]
public virtual DeferredData DeferredData { get; set; }
public int? SignedOffById { get; set; }
[ForeignKey("UserId")]
public virtual UserProfile SignedOffBy { get; set; }
}
但是,這失敗了。 事實證明, ForeignKey
需要指向MemberDataSet
類的Id。
public class MemberDataSet
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int? DeferredDataId { get; set; }
[ForeignKey("Id")]
public virtual DeferredData DeferredData { get; set; }
public int? SignedOffById { get; set; }
[ForeignKey("SignedOffById")]
public virtual UserProfile SignedOffBy { get; set; }
}
我認為這是因為這第二個關系是一對多,而第一個關系是一對零或一,有效的關系的主要結束不同,但我希望有一些明確的這個/參考好文章,所以我可以了解正在發生的事情以及ForeignKey正在做什么。
我也在尋找上面的public int? DeferredDataId { get; set; }
如何清晰public int? DeferredDataId { get; set; }
public int? DeferredDataId { get; set; }
public int? DeferredDataId { get; set; }
適合給它沒有明確地鏈接到方程式DeferredData
。 我很高興這將符合慣例,但我如何明確告訴它,例如它是否有不同的名稱? 我在這個關於使用ForeignKey
屬性的討論中看到過的例子,但這並不是所有情況下的答案!
所有的幫助非常感謝 - 希望了解問題而不是修復特定問題,因為我在模型中有很多引用,因此需要建立采用每種方法的方法。
謝謝。
編輯
添加了其他類來幫助:
public class DeferredData
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
//other properties
}
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
//other properties
}
1..0關系MemberDataSet
的必需端不應具有到DeferredData
的FK。 相反, DeferredData
的PK也應該是FK到MemberDataSet
(稱為共享主鍵)
public class MemberDataSet
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual DeferredData DeferredData { get; set; }
}
public class DeferredData
{
// DeferredData.Id is both the PK and a FK to MemberDataSet
[Key]
[DatabaseGenerated( DatabaseGeneratedOption.None )]
[ForeignKey( "MemberDataSet" )]
public int Id { get; set; }
[Required]
public virtual MemberDataSet MemberDataSet { get; set; }
}
流暢的API:
modelBuilder.Entity<MemberDataSet>()
.HasOptional( mds => mds.DeferredData )
.WithRequired()
.WillCascadeOnDelete();
我認為你是對的(前提是我理解你的權利)。 [ForeignKeyAttribute]
用於相應的外鍵。 不在鏈接對象的主鍵上。
This is my object, and the foreign key is DeferredDataId
對象中的Id
既不是外鍵(它是主鍵),也不是鏈接對象的ID
是外鍵(它是關系另一端的主鍵)
希望我理解正確:)因為我不確定。
我認為你原來的想法是正確的,只有一個例外。 通過將外鍵放在MemberDataSet
上,您暗示您想要一個零或一對多的關系。
在你的榜樣, MemberDataSet.DeferredData
是可選的, DeferredData
可以被很多人稱為MemberDataSet
實例。
在流利的語法中,這將表示為:
modelBuilder.Entity<MemberDataSet>()
.HasOptional(dataSet => dataSet.DeferredData)
.WithMany()
.HasForeignKey(deferredData => deferredData.DeferredDataId);
為了使它成為一對多或一個屬性,您可以在MemberDataSet的DeferredDataId列上放置一個唯一的(where not null)鍵約束。 這意味着DeferredData實體只能由單個MemberDataSet實體引用。
CREATE UNIQUE INDEX unique_MemberDataSet_DeferredDataId ON MemberDataSet(DeferredDataId) WHERE DeferredDataId IS NOT NULL
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.