I want to create One-To-One relationship in EF where Foreign Keys can be null (So, It can be called 0..1-to-0..1)
public class ProductInstance
{
public int Id { get; set; }
public int SaleId { get; set; }
public Sale Sale { get; set; }
}
public class Sale
{
public int Id { get; set; }
public ProductInstance ProductInstance { get; set; }
}
FluentAPI
configuration:
modelBuilder.Entity<Sale>()
.HasOptional(x => x.ProductInstance)
.WithOptionalPrincipal(x => x.Sale);
But it's generate two columns in table ProductInstance
:
Sale_id
- foreign key SaleId
Here is generated migration code:
CreateTable(
"dbo.ProductInstances",
c => new
{
Id = c.Int(nullable: false, identity: true),
SaleId = c.Int(nullable: false),
Sale_Id = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Sales", t => t.Sale_Id)
.Index(t => t.Sale_Id);
How can I do to get only one column SaleId
which will be Foreign key?
A one-to-zero-or-one relationship happens when a primary key of one table becomes PK & FK in another table in a relational database such as SQL Server.
One-to-zero-or-one with Data Annotation as follows:
public class ProductInstance
{
public int Id { get; set; }
public virtual Sale Sale { get; set; }
}
public class Sale
{
[Key]
[ForeignKey("ProductInstance")]
public int ProductInstanceId { get; set; }
///write here other properties
public virtual ProductInstance ProductInstance { get; set; }
}
One-to-zero-or-one with Fluent API as follows:
modelBuilder.Entity<ProductInstance>()
.HasOptional(s => s.Sale)
.WithRequired(ad => ad.ProductInstance);
In above case, a ProductInstance
can be saved without Sale
but the Sale
entity cannot be saved without the ProductInstance
entity. Keep in min in the above case, A ProductInstance
cannot have more than one Sale
.
We can not configure a one-to-One relationship between entities where both ends are required, meaning that the ProductInstance
entity object must include the Sale
entity object and the Sale
entity must include the ProductInstance
entity object in order to save it. One-to-one relationships are technically not possible in MS SQL Server. But we can configure one-to-One relationship between entities where both ends or at least one end is optional as follows:
One-to--one with Data Annotation as follows:
public class Department
{
[Key]
public int DepartmentId { get; set; }
ForeignKey("Person")]
public int PersonId { get; set; }
public virtual Person Person { get; set; }
}
public class Person
{
[Key]
public int PersonId { get; set; }
[ForeignKey("Department")]
public int? DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
One-to-one with Fluent API as follows:
modelBuilder.Entity<Person>()
.HasOptional(pi => pi.Department)
.WithMany()
.HasForeignKey(s => s.DepartmentId);
EF does not support one-to-one
associations with explicit FK property - there is no HasForeignKey
fluent API and if you try to workaround it with ForeignKey
data annotation, you'll get multiplicity exception during the migration.
The only solution is to remove the ProductInstance.SaleId
property, ending up with model:
public class ProductInstance
{
public int Id { get; set; }
public Sale Sale { get; set; }
}
public class Sale
{
public int Id { get; set; }
public ProductInstance ProductInstance { get; set; }
}
and configuration:
modelBuilder.Entity<Sale>()
.HasOptional(x => x.ProductInstance)
.WithOptionalPrincipal(x => x.Sale)
.Map(a => a.MapKey("SaleId"));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.