I hit an issue when trying to delete records due to FK constraints. I therefore went back to the drawing board and am trying to specify how the relationship should work.
Here are my code first classes:
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; }
}
public class DeferredData
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
//other properties
}
What I am looking to achieve is that the MemberDataSet has zero or one DeferredData. I can access DeferredData from MemberDataSet but DeferredData does not need a navigation property back to MemberDataSet. DeferredData should strictly require a MemberDataSet. In an ideal world deleting MemberDataSet will therefore delete DeferredData if assigned.
What seemed to me to be what I wanted to specify is this:
modelBuilder.Entity<MemberDataSet>().HasOptional(d => d.DeferredData).WithRequired().WillCascadeOnDelete(true);
i.e. MemberDataSet has an option DeferredData but DeferredData has a required MemberDataSet and this relationship should cascade on delete.
However, I then get an error:
The ForeignKeyAttribute on property 'DeferredData' on type 'MemberDataSet' is not valid. The foreign key name 'DeferredDataId' was not found on the dependent type 'DeferredData'. The Name value should be a comma separated list of foreign key property names.
Edit
After feeling happy with Sam's answer below I went ahead and changed a few other ForeignKey attributes. MemberDataSet has another property called SignedOffBy that is a userProfile. This previously looked like this:
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; }
public int? SignedOffById { get; set; }
[ForeignKey("SignedOffId")]
public virtual UserProfile SignedOffBy { get; set; }
}
After discussion below on what ForeignKey attribute is actually doing I changed this to:
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, I now get a very similar error message:
The ForeignKeyAttribute on property 'SignedOffBy' on type 'MemberDataSet' is not valid. The foreign key name 'UserId' was not found on the dependent type 'MemberDataSet'. The Name value should be a comma separated list of foreign key property names.
The difference here is that this relationship is Many to One i.e. 1 user can have several signedoff datasets. Is this what makes the difference? i.e. the UserProfile is now the principal object so the ForeignKey is on the MemberDataSet?
Many thanks again for any and all help.