Understanding ForeignKey attribute in entity framework code first

前端 未结 3 1856
你的背包
你的背包 2020-11-29 03:31

See the following post for some background:

Entity framework one to zero or one relationship without navigation property

I had always thought that Fore

相关标签:
3条回答
  • 2020-11-29 03:56

    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();
    
    0 讨论(0)
  • 2020-11-29 04:00

    I think that your original idea was correct, with one slight exception. By putting the foreign key on the MemberDataSet you are implying that you would like a zero-or-one-to-many relationship.

    In your example, MemberDataSet.DeferredData is optional, and DeferredData can be referred to by many MemberDataSet instances.

    In fluent syntax this would be expressed by:

    modelBuilder.Entity<MemberDataSet>()
        .HasOptional(dataSet => dataSet.DeferredData)
        .WithMany()
        .HasForeignKey(deferredData => deferredData.DeferredDataId);
    

    In order to make this a one-to-zero-or-one property you can put a unique (where not null) key constraint on MemberDataSet's DeferredDataId column. This would mean that a DeferredData entity could only be referred to by a single MemberDataSet entity.

    CREATE UNIQUE INDEX unique_MemberDataSet_DeferredDataId ON MemberDataSet(DeferredDataId) WHERE DeferredDataId IS NOT NULL
    

    Note: This type of filtered key is only available in SQL Server 2008 and up.

    0 讨论(0)
  • 2020-11-29 04:08

    I think you were right (provided that I understand you right). [ForeignKeyAttribute] is used on the coresponding foreign key. Not on the primary key of your linked object.

    This is my object, and the foreign key is DeferredDataId

    Neither the Id within your object is the foreign key (it's primary key) nor the ID of the linked object is the foreign key (it's the primary key of the other side of the relation)

    Hope I understood you correctly :) Because I'm not sure.

    0 讨论(0)
提交回复
热议问题