Let's pretend I have three tables, each with a primary key called Id
:
TableA
------
Id
TableB
------
Id
TableC
-----
Id
The intent is for each of these entities to have a one-to-one navigation property with each other so that I may navigate in any direction given any of the entities. Unfortunately, I have not found a combination of [Key]
, [ForeignKey]
, and navigation properties that allows this more than once per entity.
For example, this works (Entity Framework thinks TableA
is the principal in the 1:1 relationship):
public class TableA
{
[Key]
[Required]
public Guid Id { get; set; }
public virtual TableB TableB { get; set; }
public virtual TableC TableB { get; set; }
}
public class TableB
{
[Key]
[ForeignKey("TableA")]
[Required]
public Guid Id { get; set; }
public virtual TableA TableA { get; set; }
}
but this doesn't work:
public class TableB
{
[Key]
[ForeignKey("TableA,TableC")] // The constructor documentation says this will work, but at runtime it throws an exception
[Required]
public Guid Id { get; set; }
public virtual TableA TableA { get; set; }
public virtual TableC TableC { get; set; }
}
nor does this:
public class TableB
{
[Key]
[Required]
public Guid Id { get; set; }
[ForeignKey("Id")]
public virtual TableA TableA { get; set; }
[ForeignKey("Id")]
public virtual TableC TableC { get; set; }
}
How can I use attributes to allow these relationships? Currently, if I want to navigate to TableC
from TableB
, I must navigate through TableA
, causing an extra unnecessary database lookup. It seems Entity Framework wants to force a hierarchical relationship where there may be none.
I think what you need is a model like this:
public class TableA
{
[Key]
public Guid Id { get; set; }
public virtual TableB TableB { get; set; }
public virtual TableC TableC { get; set; }
}
public class TableB
{
[Key]
[ForeignKey("TableA")]
public Guid Id { get; set; }
public virtual TableA TableA { get; set; }
public virtual TableC TableC { get; set; }
}
public class TableC
{
[Key]
[ForeignKey("TableB")]
public Guid Id { get; set; }
public virtual TableB TableB { get; set; }
[Required]
public virtual TableA TableA { get; set; }
}
You don't need to specify a FK property for TableC
navigation property in the TableB
entity because TableB
is principal in the relationship between B and C.
Try removing the Required
data annotation and configuring the relationship this way, overriding the OnModelCreating
method on your context:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TableA>().HasOptional(a => a.TableC).WithOptionalPrincipal(c => c.TableA);
base.OnModelCreating(modelBuilder);
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments