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

查看:25
本文介绍了先了解实体框架代码中的 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 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天全站免登陆