Ale*_*kov 0 c# entity-framework one-to-one
我想在EF中创建一对一关系,其中外键可以为null(因此,它可以被称为0..1到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; }
}
Run Code Online (Sandbox Code Playgroud)
FluentAPI 组态:
modelBuilder.Entity<Sale>()
.HasOptional(x => x.ProductInstance)
.WithOptionalPrincipal(x => x.Sale);
Run Code Online (Sandbox Code Playgroud)
但它在表中生成两列ProductInstance:
Sale_id - 外键SaleId这是生成的迁移代码:
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);
Run Code Online (Sandbox Code Playgroud)
如何才能只获得一列SaleId外键?
当一个表的主键在关系数据库(如SQL Server)中的另一个表中变为PK&FK时,会发生一对多或一对一的关系.
数据注释一对一或一,如下:
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; }
}
Run Code Online (Sandbox Code Playgroud)
使用Fluent API进行一对一或一对一,如下所示:
modelBuilder.Entity<ProductInstance>()
.HasOptional(s => s.Sale)
.WithRequired(ad => ad.ProductInstance);
Run Code Online (Sandbox Code Playgroud)
在上述情况下,ProductInstance可以保存a,Sale但是没有Sale实体就无法保存ProductInstance实体.在上述情况下保持最小,A ProductInstance不能超过一个Sale.
我们无法在需要两端的实体之间配置一对一关系,这意味着ProductInstance实体对象必须包含Sale实体对象,并且Sale实体必须包含ProductInstance实体对象才能保存它.在MS SQL Server中,技术上不可能实现一对一关系.但我们可以在实体之间配置一对一关系,其中两端或至少一端是可选的,如下所示:
与Data Annotation一对一如下:
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; }
}
Run Code Online (Sandbox Code Playgroud)
与Fluent API一对一如下:
modelBuilder.Entity<Person>()
.HasOptional(pi => pi.Department)
.WithMany()
.HasForeignKey(s => s.DepartmentId);
Run Code Online (Sandbox Code Playgroud)
EF不支持one-to-one具有显式FK属性的关联-没有HasForeignKey流畅的API,并且如果您尝试通过ForeignKey数据注释来解决它,则在迁移期间会遇到多重异常。
唯一的解决方案是删除ProductInstance.SaleId属性,最终得到模型:
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; }
}
Run Code Online (Sandbox Code Playgroud)
和配置:
modelBuilder.Entity<Sale>()
.HasOptional(x => x.ProductInstance)
.WithOptionalPrincipal(x => x.Sale)
.Map(a => a.MapKey("SaleId"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2571 次 |
| 最近记录: |