How to Create a One-to-One Relationship Using a Non-Primary Key (EF First Code)
I have two classes: "Car" and "CarDetails"
public class Car {
public int Id { get; set; }
public Guid CarGuid { get; set; }
public string Name { get; set; }
public virtual CarDetails CarDetails { get; set; }
}
public class CarDetails {
public int Id { get; set; }
public Guid CarGuid { get; set; }
public string Color { get; set; }
public int Weight { get; set; }
[ForeignKey("CarGuid")]
public virtual Car Car { get; set; }
}
Now I want to create a link between two classes using "CarGuid", but EF won't let me do that, please help me!
source to share
You cannot create a one-to-one (or one-to-one) relationship between two EF SQL entities / tables using a non-primary key property / column. You should be using primary key columns to achieve this kind of relationship with EF.
public class Car
{
public int Id { get; set; }
public Guid CarGuid { get; set; }
public string Name { get; set; }
public virtual CarDetails CarDetails { get; set; }
}
public class CarDetails
{
[Key, ForeignKey("Car")]
public int Id { get; set; }
public Guid CarGuid { get; set; }
public string Color { get; set; }
public int Weight { get; set; }
public virtual Car Car { get; set; }
}
With the above relationship you will get Car
as principal and as CarDetails
dependent. By having CarDetails.Id
both the primary key CarDetails
and the foreign key referencing Car.Id
, you can ensure that each Car
has at most 1 CarDetails
.
However, this is not technically a relationship 1<->1
... it is a relationship 1<->0..1
. This type of model will allow you to create objects Car
without corresponding objects CarDetils
.
If you need something closer to a relationship 1<->1
, I believe the only way to do it is with a free modeler:
public class CarsDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>();
modelBuilder.Entity<CarDetails>()
.HasRequired(x => x.Car).WithRequiredDependent(x => x.CarDetails)
;
base.OnModelCreating(modelBuilder);
}
}
In the above definition, you cannot save Car
unless you save the corresponding CarDetails
one within the same SaveChanges operation. This will be as close to as possible 1<->1
as the object accepts. Similarly, you can achieve the same on the other side of the relationship:
public class CarsDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasRequired(x => x.CarDetails).WithRequiredPrincipal(x => x.Car)
;
modelBuilder.Entity<CarDetails>();
base.OnModelCreating(modelBuilder);
}
}
source to share