首先了解实体框架代码中的 ForeignKey 属性 [英] Understanding ForeignKey attribute in entity framework code first
问题描述
有关背景信息,请参阅以下帖子:
See the following post for some background:
我一直认为 ForeignKey
用于显示类中的哪个属性持有决定导航属性的 ForeignKey,例如
I had always thought that ForeignKey
was used to show which property in a class held the ForeignKey that determined the navigation property e.g.
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 我实际上需要:
However, I discovered on the linked post that this is not right and that as DeferredData's primary key was called Id I actually needed:
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
用于指向另一个类.
i.e. ForeignKey
is used to point to the other class.
然后我开始更改其他一些引用:
I then proceeded to change some of the other references:
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.
However, this failed. Turned out on this one the ForeignKey
needed to point to the Id on MemberDataSet
class.
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 正在做什么.
I presume this is because this second relationship is one to many whereas the first was one to zero or one, and that effectively the principal end of the relationship differs, but I would appreciate some clarity on this/references to good articles, so I can understand what is happening and exactly what ForeignKey is doing.
我也在上面的例子中寻找清楚如何 public int?DeferredDataId { 获取;放;}
适合等式,因为它没有明确链接到 DeferredData
.我很高兴这将按照惯例匹配,但我将如何明确地告诉它,例如如果它有一个不同的名字?我在这个讨论中看到的所有示例都是关于使用 ForeignKey
属性的,但这不能作为上述所有情况的答案!
I was also looking for clarity in the example above of how public int? DeferredDataId { get; set; }
fits into the equation given it is not explicitly linked to DeferredData
. I am happy this will match up by convention but how would I explicitly tell it this e.g. if it had a different name? Al the examples I have seen on this talk about using the ForeignKey
attribute but this can't be the answer in all cases per above!
非常感谢所有帮助 - 希望了解问题而不是解决特定问题,因为我的模型中有很多参考资料,因此需要确定对每个问题采取的方法.
All help greatly appreciated - looking to understand the issue rather than fix a specific problem as I have lots of references in my model so need to establish what approach to take with each.
谢谢.
编辑
添加了其他类来帮助:
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 也应该是对 MemberDataSet
的 FK(称为共享主键)
The required side of the 1..0 relationship MemberDataSet
should not have a FK to DeferredData
. Instead, DeferredData
's PK should also be a FK to MemberDataSet
(known as shared primary key)
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();
这篇关于首先了解实体框架代码中的 ForeignKey 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!