如何将实体映射到包含层次结构的维度表?

时间:2011-07-05 17:45:45

标签: c# entity-framework entity-framework-4.1 data-warehouse dimensional-modeling

考虑以下层次结构:

Department -> Category -> Product

(每个部门包含多个类别,每个类别包含多个产品。)

使用Kimball dimensional modeling方法,我创建了一个包含以下列的ProductDim表:

ProductKey
Product
Category
Department

我正在尝试使用EF 4.1将我的DepartmentCategoryProduct实体映射到ProductDim表。以下是相关类的简化版本:

public class Department
{
    public string Name { get; set; }
}

public class Category
{
    public string Name { get; set; }
}

public class Product
{
    public string Name { get; set; }
}

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Department>().ToTable("ProductDim");
        modelBuilder.Entity<Department>().HasKey(t => t.Name);
        modelBuilder.Entity<Department>().Property(t => t.Name).HasColumnName("Department");

        modelBuilder.Entity<Category>().ToTable("ProductDim");
        modelBuilder.Entity<Category>().HasKey(t => t.Name);
        modelBuilder.Entity<Category>().Property(t => t.Name).HasColumnName("Category");

        modelBuilder.Entity<Product>().ToTable("ProductDim");
        modelBuilder.Entity<Product>().HasKey(t => t.Name);
        modelBuilder.Entity<Product>().Property(t => t.Name).HasColumnName("Product");
    }
}

问题在于,当我尝试使用这些类时,我得到以下异常:

  

System.InvalidOperationException:The   实体类型'类别'和   '部门'不能共享表   'ProductDim'因为它们不在   相同类型的层次结构或没有   有效的一对一外键   与匹配主要的关系   他们之间的关键。

这有什么解决方法吗?如果没有,Entity Framework是否可以成功地与维度建模的数据库一起使用?

2 个答案:

答案 0 :(得分:3)

实体框架只能使用正确建模和规范化的关系(OLTP)数据库。数据仓库适用于商业智能(OLAP)工具,不适用于ORM映射。您不会将表映射到您的实体 - 实体框架无法执行此操作。

因为错误说EF只允许在以下情况下将多个实体映射到同一个表:

  • 您正在使用Table per type inheritance(这意味着您的实体必须位于继承层次结构中)。您的实体显然不属于同一继承结构。
  • 您正在使用表拆分,其中一个表被拆分为多个以一对一关系相关的实体。

答案 1 :(得分:0)

关于你代码的事情似乎并不合适。 你应该像下面的例子那样创建Product类。

public class Department
{
    public string Name { get; set; }
    public List<Category> Categories { get; set; }
}

你的类别类应该是这样的。

public class Category
{
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}

这跟随你的部门逻辑有许多具有许多产品的类别。