EF Core 表之间的一对一关系
EF Core One to One Relationionship between tables
在 EF Core 中,我首先设置了两个对象和流畅的代码
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public PlatForm Platform { get; set; }
}
public class Platform
{
public int Id { get; set; }
public string PlatformName { get; set; }
public Customer Customer { get; set; }
}
modelBuilder.Entity<Platform>(entity =>
{
entity.ToTable("Platform").HasKey(e => e.Id);
entity.HasOne(t => t.Customer)
.WithOne(t => t.Platform)
.HasForeignKey<Customer>(t => t.Id).IsRequired();
});
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).HasPrecision(50).IsRequired().HasColumnName("name");
});
添加平台时,您应该select 为其所属的客户。
您可以添加客户没有平台但不能添加没有客户的平台。
当我尝试添加客户时出现异常
the property is also part of a foreign key for which the principal
entity in the relationship is not known.
“您可以在没有平台的情况下添加客户,但不能在没有客户的情况下添加平台。”
这表示一对 0 或 1 的关系或本质上是受限的 many-to-one,其中平台将包含与其相关的客户的 FK (CustomerId):
为 FK 实施阴影 属性:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public PlatForm Platform { get; set; }
}
public class Platform
{
public int Id { get; set; }
public string PlatformName { get; set; }
public Customer Customer { get; set; }
}
modelBuilder.Entity<Platform>(entity =>
{
entity.ToTable("Platform").HasKey(e => e.Id);
entity.HasOne(t => t.Customer)
.WithOne(t => t.Platform)
.HasForeignKey<Platform>("CustomerId").IsRequired();
});
架构会将其视为 many-to-one,从技术上讲,没有任何东西可以阻止您尝试创建引用同一客户的第二个平台,但就 EF 域而言,一个客户可以有 0-1 个平台,一个平台需要有 1 个客户。将关系建立为聚合根 where-by 通常是个好主意,您不要将平台称为 top-level 实体,只能通过客户访问它。 (没有平台 DbSet 在 DbContext 中公开)
使用 EF Core,您还可以探索将其设置为客户下的“拥有”关系,它可以采用相同的架构或在客户下嵌入平台实体字段 table。这加强了实体之间的聚合根关系。
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer").HasKey(e => e.Id);
entity.OwnsOne(t => t.Platform)
.HasForeignKey<Platform>("CustomerId"); // <- not sure if this is needed
});
我不是 100% 跨所有关系,但对于 EF Core 3.1+,它确实支持单独的 table 关系,我认为这是关系可选的要求。 (0-1 平台)使用 OwnsOne 而不是 HasOne
/WithOne
的优势在于,这限制了 EF 允许通过 DbSet
或使用 Set<Platform>
访问拥有的实体.使用 HasOne
,一些后来的编码人员可以尝试通过添加一个平台 DbSet 或执行类似以下操作来“破解”没有 Platforms DbSet:
var customer = context.Customers.Single(x => x.Id == customerId);
var platform = new Platform { Customer = customer };
context.Set<Platform>().Add(platform);
context.SaveChanges();
这会产生各种后果,因为加载的客户可能已经关联了一个平台,即使不是急切加载,引用也可能会被加载并替换为可能不是预期的代码。对于 Owned 关系,不允许使用此代码。
在 EF Core 中,我首先设置了两个对象和流畅的代码
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public PlatForm Platform { get; set; }
}
public class Platform
{
public int Id { get; set; }
public string PlatformName { get; set; }
public Customer Customer { get; set; }
}
modelBuilder.Entity<Platform>(entity =>
{
entity.ToTable("Platform").HasKey(e => e.Id);
entity.HasOne(t => t.Customer)
.WithOne(t => t.Platform)
.HasForeignKey<Customer>(t => t.Id).IsRequired();
});
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).HasPrecision(50).IsRequired().HasColumnName("name");
});
添加平台时,您应该select 为其所属的客户。 您可以添加客户没有平台但不能添加没有客户的平台。
当我尝试添加客户时出现异常
the property is also part of a foreign key for which the principal entity in the relationship is not known.
“您可以在没有平台的情况下添加客户,但不能在没有客户的情况下添加平台。”
这表示一对 0 或 1 的关系或本质上是受限的 many-to-one,其中平台将包含与其相关的客户的 FK (CustomerId):
为 FK 实施阴影 属性:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public PlatForm Platform { get; set; }
}
public class Platform
{
public int Id { get; set; }
public string PlatformName { get; set; }
public Customer Customer { get; set; }
}
modelBuilder.Entity<Platform>(entity =>
{
entity.ToTable("Platform").HasKey(e => e.Id);
entity.HasOne(t => t.Customer)
.WithOne(t => t.Platform)
.HasForeignKey<Platform>("CustomerId").IsRequired();
});
架构会将其视为 many-to-one,从技术上讲,没有任何东西可以阻止您尝试创建引用同一客户的第二个平台,但就 EF 域而言,一个客户可以有 0-1 个平台,一个平台需要有 1 个客户。将关系建立为聚合根 where-by 通常是个好主意,您不要将平台称为 top-level 实体,只能通过客户访问它。 (没有平台 DbSet 在 DbContext 中公开)
使用 EF Core,您还可以探索将其设置为客户下的“拥有”关系,它可以采用相同的架构或在客户下嵌入平台实体字段 table。这加强了实体之间的聚合根关系。
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer").HasKey(e => e.Id);
entity.OwnsOne(t => t.Platform)
.HasForeignKey<Platform>("CustomerId"); // <- not sure if this is needed
});
我不是 100% 跨所有关系,但对于 EF Core 3.1+,它确实支持单独的 table 关系,我认为这是关系可选的要求。 (0-1 平台)使用 OwnsOne 而不是 HasOne
/WithOne
的优势在于,这限制了 EF 允许通过 DbSet
或使用 Set<Platform>
访问拥有的实体.使用 HasOne
,一些后来的编码人员可以尝试通过添加一个平台 DbSet 或执行类似以下操作来“破解”没有 Platforms DbSet:
var customer = context.Customers.Single(x => x.Id == customerId);
var platform = new Platform { Customer = customer };
context.Set<Platform>().Add(platform);
context.SaveChanges();
这会产生各种后果,因为加载的客户可能已经关联了一个平台,即使不是急切加载,引用也可能会被加载并替换为可能不是预期的代码。对于 Owned 关系,不允许使用此代码。