首先了解实体框架代码中的 ForeignKey 属性 [英] Understanding ForeignKey attribute in entity framework code first

查看:37
本文介绍了首先了解实体框架代码中的 ForeignKey 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关背景信息,请参阅以下帖子:

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屋!

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