了解ForeignKey的属性在实体框架code第一 [英] Understanding ForeignKey attribute in entity framework code first

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

问题描述

请参阅以下职位的一些背景:

<一个href=\"http://stackoverflow.com/questions/21851889/entity-framework-one-to-zero-or-one-relationship-without-navigation-property\">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 方程。我很高兴,这将按照惯例相符了,但我怎么会明确告诉它该如如果它有一个不同的名字?阿尔我看到的这个说说使用 ForeignKey的属性的例子,但这个不能在按照上述所有情况下的答案!

所有帮助很大AP preciated - 看明白的问题,而不是解决一个具体的问题,因为我有很多在我的模型引用,所以需要建立到采取什么样的方式与每个

感谢。

修改

添加其他类的帮助:

公共类DeferredData
{    [键]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
    公众诠释标识{搞定;组; }    //其他属性
}公共类用户配置
{    [键]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
    公众诠释用户ID {搞定;组; }    //其他属性
}


解决方案

在1..0关系所需的侧 MemberDataSet 应该不会有FK到 DeferredData 。相反, DeferredData 的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&LT; MemberDataSet&GT;()
    .HasOptional(MDS =&GT; 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第一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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