Reputation: 3931
I have the following classes (shortened for brevity);
public class InsurancePolicy : AuditableEntity<int>
{
[Column("id"), Key]
public override int ID { get; set; }
[Column("deviceid"), ForeignKey("Device")]
public int DeviceId { get; set; }
public virtual Device Device { get; set; }
}
public partial class Device : AuditableEntity<int>
{
[Column("deviceid"), Key]
public override int ID { get; set; }
[ForeignKey("Policy")]
public int PolicyId { get; set; }
public virtual InsurancePolicy Policy { get; set; }
[ForeignKey("Vehicle")]
public int VehicleId { get; set; }
public virtual Vehicle Vehicle { get; set; }
}
public partial class Vehicle : AuditableEntity<int>
{
[Column("id"), Key]
public override int ID { get; set; }
[Column("deviceid"), ForeignKey("Device")]
public int DeviceId { get; set; }
public virtual Device Device { get; set; }
public virtual List<InsurancePolicyVehicle> InsurancePolicyVehicles { get; set; }
}
Now when I try and run my update-database
command I get this error:
Device_Policy_Target: : Multiplicity is not valid in Role 'Device_Policy_Target' in relationship 'Device_Policy'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
Device_Vehicle_Target: : Multiplicity is not valid in Role 'Device_Vehicle_Target' in relationship 'Device_Vehicle'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
Could anyone please advise what I am doing wrong here?
Upvotes: 2
Views: 83
Reputation: 41539
Taking the Device_Policy_Target
relationship as an example, you have the following (trimming down to the the relevant properties for this relationship):
public class InsurancePolicy : AuditableEntity<int>
{
[Column("id"), Key]
public override int ID { get; set; }
[Column("deviceid"), ForeignKey("Device")]
public int DeviceId { get; set; }
public virtual Device Device { get; set; }
}
public partial class Device : AuditableEntity<int>
{
[Column("deviceid"), Key]
public override int ID { get; set; }
[ForeignKey("Policy")]
public int PolicyId { get; set; }
public virtual InsurancePolicy Policy { get; set; }
}
What you're defining here is a one-to-one relationship. EF only supports such relationships where the two tables share the primary key. In your configuration your child table - InsurancePolicy
has its own PK, and a Foreign Key to Device
. EF only supports one-to-many relationships with these constraints.
To define these relationships to be one-to-one, switch your setup to something along the lines of:
public class InsurancePolicy : AuditableEntity<int>
{
[Column("deviceid"), Key, ForeignKey("Device")]
public override int ID { get; set; }
public virtual Device Device { get; set; }
}
public partial class Device : AuditableEntity<int>
{
[Column("deviceid"), Key]
public override int ID { get; set; }
public virtual InsurancePolicy Policy { get; set; }
}
This is all partially a consequence of EF not supporting unique constraints. This article has a fuller explanation of one-to-one relationships using DataAnnotations
Update:
To "fake" the one-to-one using the tables/keys you've got then consider something like this:
public class InsurancePolicy : AuditableEntity<int>
{
[Column("id"), Key]
public override int ID { get; set; }
[Column("deviceid"), ForeignKey("Device")]
public int DeviceId { get; set; }
public virtual Device Device { get; set; }
}
public partial class Device : AuditableEntity<int>
{
[Column("deviceid"), Key]
public override int ID { get; set; }
public virtual IEnumerable<InsurancePolicy> PoliciesAsList { get; set; }
[NotMapped]
public virtual InsurancePolicy Policy {
get {
return (PoliciesAsList != null)
? PoliciesAsList.FirstOrDefault()
: null;
}
}
}
In this case I've arbitrarly chosen Device
as the parent - it's not important which you choose.
You should also make sure that the database has a unique constraint on deviceid
on the InsurancePolicy table.
Upvotes: 1