Reputation: 41
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 relationship between two classes by 'CarGuid', but EF won't allow me to do so, Please help me!
Upvotes: 4
Views: 3327
Reputation: 47375
You cannot create a one-to-one (or one-to-zero or one) relationship between two EF entities / SQL tables using a non-primary-key property / column. You have to use 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 end up having Car
as the principal, and CarDetails
as the dependent. By having CarDetails.Id
be both the primary key of CarDetails
and the foreign key referencing Car.Id
, you can ensure that each Car
has no more than 1 CarDetails
.
However, this is technically not a 1<->1
relationship... it is a 1<->0..1
relationship. This type of model will allow Car
objects to exist without any corresponding CarDetils
objects.
If you want something closer to a 1<->1
relationship, I believe the only way to do that is with the fluent model builder:
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);
}
}
With the above definition, you cannot save a Car
unless you also save a corresponding CarDetails
within the same SaveChanges operation. This is as close to a 1<->1
as entityframework will take you. You can achieve the same thing from the other side of the relationship in a similar way:
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);
}
}
Upvotes: 2