我正在尝试使用代码优先方法(星型架构)构建数据仓库 (DWH):
事实/维度类:
[Table("FactBase")]
public class FactBase
{
[Key]
public Guid Id { get; set; }
[ForeignKey("DimTest1")]
public string DimDigitalesBuchISBN { get; set; }
public virtual DimTest1 DimTest1 { get; set; }
}
[Table("DimTest1")]
public class DimTest1
{
[Key]
public string ISBN { get; set; }
public string Bla { get; set; }
}
上下文:
public class XDBContextDWH : DbContext
{
public DbSet<FactBase> FactBase { get; set; }
public DbSet<DimTest1> DimTest1 { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(new string("connection string"));
}
}
使用迁移后,架构如下所示:
基于那个star schema,不应该是这样的关系(这里:SQL)吗?
答案 0 :(得分:0)
当您指定属性 [ForeignKey("DimTest1")]
时,您是在告诉 EF 使用 DimTest1
作为 FactBase
类的导航属性,而不是指向 DimTest1
类。
但由于该属性不存在,因此不会创建关系。
将您的课程更改为:
[Table("FactBase")]
public class FactBase
{
[Key]
public Guid Id { get; set; }
[ForeignKey("DimTest1")]
public string DimDigitalesBuchISBN { get; set; }
public virtual DimTest1 DimTest1 { get; set; } // navigation property
}
这应该使它按预期工作。
答案 1 :(得分:0)
正如您所暗示的那样,星型架构事实表应该使用由它所引用的外键组成的复合键。 所以我想说你的情况有几个问题需要解决。 首先,事实表可能不应该有一个名为 Id 的列,尽管它不会真正伤害任何东西,它可能永远不会用于查询,因此您只是添加了占用磁盘空间的额外数据。 其次,可能您正在寻找的答案是,如果您想在事实表上使用复合主键,则需要在数据库上下文中指定。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<FactBase>()
.HasKey(x => new { x.Id, x.DimDigitalesBuchISBN });
}
正如我所提到的,您可能不希望在您的 PK 中包含 Fact.Id 列,而是会像这样引用多个维度:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<FactBase>()
.HasKey(x => new { x.Dim1Id, x.Dim2Id, x.Dim3Id});
}
其中 Dim1Id、Dim2Id 和 Dim3Id 是维度的主键。 我还应该提到,您需要从 FactBase 类的 Id 字段中删除 [Key] 属性。
参考:https://docs.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations