问题描述
请参阅以下职位的一些背景:
Entity框架一到零或没有导航属性一对一的关系。
我以前一直以为 ForeignKey的
被用来显示其财产中的一类认为,确定的导航属性例如在ForeignKey的。
公共类MemberDataSet
{
[键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; } 公众诠释? DeferredDataId {搞定;组; }
[ForeignKey的(DeferredDataId)]
公共虚拟DeferredData DeferredData {搞定;组; }
}
不过,我发现,对链接后,这是不对的,作为DeferredData的主键名为id我真正需要的:
公共类MemberDataSet
{
[键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; } 公众诠释? DeferredDataId {搞定;组; }
[ForeignKey的(ID)]
公共虚拟DeferredData DeferredData {搞定;组; }
}
即。 ForeignKey的
用于指向其他类。
我随后开始改变一些其他参考文献:
公共类MemberDataSet
{
[键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; } 公众诠释? DeferredDataId {搞定;组; }
[ForeignKey的(ID)]
公共虚拟DeferredData DeferredData {搞定;组; } 公众诠释? SignedOffById {搞定;组; }
[ForeignKey的(用户ID)]
公共虚拟用户配置SignedOffBy {搞定;组; }
}
然而,该失败。在这一个横空出世的 ForeignKey的
需要指向标识上的 MemberDataSet
类。
公共类MemberDataSet
{
[键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; } 公众诠释? DeferredDataId {搞定;组; }
[ForeignKey的(ID)]
公共虚拟DeferredData DeferredData {搞定;组; } 公众诠释? SignedOffById {搞定;组; }
[ForeignKey的(SignedOffById)]
公共虚拟用户配置SignedOffBy {搞定;组; }
}
我presume这是因为这第二个关系是一对多,而第一次是一个0或1,而有效的关系的主要终点不同,但我想AP preciate一些清晰度上这种/好文章的引用,这样我就可以明白发生了什么和什么ForeignKey的是做。
我也一直在寻找的清晰度在上面的例子中如何公众诠释的? DeferredDataId {搞定;组; }
适合给它没有明确地链接到 DeferredData code>方程。我很高兴,这将按照惯例相符了,但我怎么会明确告诉它该如如果它有一个不同的名字?阿尔我看到的这个说说使用
ForeignKey的
属性的例子,但这个不能在按照上述所有情况下的答案!
所有帮助很大AP preciated - 看明白的问题,而不是解决一个具体的问题,因为我有很多在我的模型引用,所以需要建立到采取什么样的方式与每个
感谢。
修改
添加其他类的帮助:
公共类DeferredData
{ [键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; } //其他属性
}公共类用户配置
{ [键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释用户ID {搞定;组; } //其他属性
}
在1..0关系所需的侧 MemberDataSet
应该不会有FK到 DeferredData code>。相反,
DeferredData code>的PK也应该是FK到
MemberDataSet
(被称为共享主键)
公共类MemberDataSet
{
[键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; } 公共虚拟DeferredData DeferredData {搞定;组; }
}公共类DeferredData
{
// DeferredData.Id既是PK和一个FK到MemberDataSet
[键]
[DatabaseGenerated(DatabaseGeneratedOption.None)
[ForeignKey的(MemberDataSet)]
公众诠释标识{搞定;组; } [需要]
公共虚拟MemberDataSet MemberDataSet {搞定;组; }
}
流利的API:
modelBuilder.Entity< MemberDataSet>()
.HasOptional(MDS => mds.DeferredData)
.WithRequired()
.WillCascadeOnDelete();
See the following post for some background:
Entity framework one to zero or one relationship without navigation property
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; }
}
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; }
}
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; }
}
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; }
}
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.
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.
Thanks.
Edit
Added other classes to help:
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
}
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; }
}
Fluent API:
modelBuilder.Entity<MemberDataSet>()
.HasOptional( mds => mds.DeferredData )
.WithRequired()
.WillCascadeOnDelete();
这篇关于了解ForeignKey的属性在实体框架code第一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!