使用 Fluent API 的 EF Core 中的一对一关系
One to one relation in EF Core using Fluent API
我正在使用 EF Core 2.1
如何在 EF Core 中映射一对一关系。我有 Customer
& Course
域实体,其中一位客户将拥有一门课程。
这是我的客户和 CoursePOCO 的样子。
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course
{
public int Id { get; set; }
public string CouseName { get; set; }
public virtual Customer Customer { get; set; }
}
我正在使用 FluentAPI。
public class CourseConfiguration : IEntityTypeConfiguration<Course>
{
public void Configure(EntityTypeBuilder<Parent> builder)
{
builder.HasKey(x => x.Customer.Id) //not allowing -> throws error
//The properties expression 'x => Convert(x.Customer.Id, Object)' is not valid.
// The expression should represent a simple property access: 't => t.MyProperty'.
// When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.
// Parameter name: propertyAccessExpression
}
}
由于是一对一关系,我不想在 Contact (FK -CustomerId) 中创建额外的键,
主要要求:-
我想将 Id
(在课程中)定义为 PK + FK
并且在此关系中客户是父实体。
如果我是基于配置的迁移,我会这样做:-
public class Course
{
[Key]
[ForeignKey("Customer")]
public int Id { get; set; }
public string Name { get; set; }
public virtual Customer Customer { get; set; }
}
我想在 EF Core 中使用 Fluent API 做同样的事情??
谢谢!!
类似于下面的内容应该有所帮助。 HasOne 方法与 WithOne 链接将有助于建立一对一关系:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course
{
public int Id { get; set; }
public string CourseName { get; set; }
public int CustomerId {get;set;}
public virtual Customer Customer { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>()
.HasOne(a => a.Customer)
.WithOne(b => b.Course)
.HasForeignKey<Course>(b => b.CustomerId);
}
正如其他答案指出的那样,关键点是使用 HasForeignKey<>()
方法配置外键。
但要注意外键应该设置在依赖实体上,而不是主体实体上。
详细方法:
为 Customer
添加导航 属性 到 Course
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public Course Course {get;set;}
}
现在将 Course.Id
设置为引用 Customer.Id
的 FK
public class AppDbContext : DbContext
{
public AppDbContext (DbContextOptions<AppDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Customer>(entity=>
{
entity.HasOne(customer=>customer.Course)
.WithOne(course=> course.Customer)
.HasForeignKey<Course>(course=>course.Id);
});
}
public DbSet<App.Models.Customer> Customer { get; set; }
public DbSet<App.Models.Course> Courses{ get; set; }
}
生成的 sql 脚本是:
CREATE TABLE [Customer] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY ([Id])
);
GO
CREATE TABLE [Courses] (
[Id] int NOT NULL,
[CouseName] nvarchar(max) NULL,
CONSTRAINT [PK_Courses] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Courses_Customer_Id] FOREIGN KEY ([Id]) REFERENCES [Customer] ([Id]) ON DELETE CASCADE
);
GO
我正在使用 EF Core 2.1
如何在 EF Core 中映射一对一关系。我有 Customer
& Course
域实体,其中一位客户将拥有一门课程。
这是我的客户和 CoursePOCO 的样子。
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course
{
public int Id { get; set; }
public string CouseName { get; set; }
public virtual Customer Customer { get; set; }
}
我正在使用 FluentAPI。
public class CourseConfiguration : IEntityTypeConfiguration<Course>
{
public void Configure(EntityTypeBuilder<Parent> builder)
{
builder.HasKey(x => x.Customer.Id) //not allowing -> throws error
//The properties expression 'x => Convert(x.Customer.Id, Object)' is not valid.
// The expression should represent a simple property access: 't => t.MyProperty'.
// When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.
// Parameter name: propertyAccessExpression
}
}
由于是一对一关系,我不想在 Contact (FK -CustomerId) 中创建额外的键,
主要要求:-
我想将 Id
(在课程中)定义为 PK + FK
并且在此关系中客户是父实体。
如果我是基于配置的迁移,我会这样做:-
public class Course
{
[Key]
[ForeignKey("Customer")]
public int Id { get; set; }
public string Name { get; set; }
public virtual Customer Customer { get; set; }
}
我想在 EF Core 中使用 Fluent API 做同样的事情??
谢谢!!
类似于下面的内容应该有所帮助。 HasOne 方法与 WithOne 链接将有助于建立一对一关系:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course
{
public int Id { get; set; }
public string CourseName { get; set; }
public int CustomerId {get;set;}
public virtual Customer Customer { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>()
.HasOne(a => a.Customer)
.WithOne(b => b.Course)
.HasForeignKey<Course>(b => b.CustomerId);
}
正如其他答案指出的那样,关键点是使用 HasForeignKey<>()
方法配置外键。
但要注意外键应该设置在依赖实体上,而不是主体实体上。
详细方法:
为 Customer
Course
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public Course Course {get;set;}
}
现在将 Course.Id
设置为引用 Customer.Id
FK
public class AppDbContext : DbContext
{
public AppDbContext (DbContextOptions<AppDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Customer>(entity=>
{
entity.HasOne(customer=>customer.Course)
.WithOne(course=> course.Customer)
.HasForeignKey<Course>(course=>course.Id);
});
}
public DbSet<App.Models.Customer> Customer { get; set; }
public DbSet<App.Models.Course> Courses{ get; set; }
}
生成的 sql 脚本是:
CREATE TABLE [Customer] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY ([Id])
);
GO
CREATE TABLE [Courses] (
[Id] int NOT NULL,
[CouseName] nvarchar(max) NULL,
CONSTRAINT [PK_Courses] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Courses_Customer_Id] FOREIGN KEY ([Id]) REFERENCES [Customer] ([Id]) ON DELETE CASCADE
);
GO