复合键实体,不想声明PK键

时间:2018-03-01 08:22:08

标签: c# entity-framework entity-framework-6 ef-code-first

好的,这应该很简单。我有一个班级

public class ProductConfig
{
   public Category { get;set; }
   public Product { get;set; }
}

这两个导航属性也是表的主键。 声明PRoductId和CategoryIds是冗余的。如何使用导航属性配置主键?

编辑:愚蠢的我。我在上面的问题中遗忘了一些非常重要的内容以上两点是指出配置。然后我们有第三个fk,它是所选产品和类别组合的配置。因此,上面的实体必须是物化实体

public class ProductConfig
{
   public Category { get;set; }
   public Product { get;set; }
   public ProductCategoryType { get; set; }
}

2 个答案:

答案 0 :(得分:2)

  

声明ProductId和CategoryId是多余的。如何使用导航属性配置主键?

很快 - 你不能。虽然EF6支持基于阴影属性的FK,但它没有提供使用阴影属性名称配置PK(以及许多其他列相关设置)的方法 - [Key][Column]数据注释无法应用于导航property和HasKey fluent API需要原始属性选择器表达式。通常,EF6不支持PK中的阴影属性。

所有这些限制已在EF Core中删除。但是在EF6中,冗余与否,你必须定义实体中的实际原始属性并将它们映射到复合PK。

答案 1 :(得分:0)

您只需通过导航属性在Product和Category实体之间建立关系。 EF将根据自己的多对多关系设置正确的表结构。所以不需要自己的关系实体。 请检查一下:many-to-many-relationship in EF

e.g:

产品类别:

public class Product
{
    // other properties

    public virtual ICollection<Category> Categories { get; set; }
}

分类:

public class Category
{
    // other properties

    public virtual ICollection<Product> Products { get; set; }
}

或者我误解了你的问题?

修改 如果您需要一个像ProductConfig这样的独立实体,那么您应该尝试通过以下方式将其设置为唯一索引约束:

modelBuilder
    .Entity<ProductConfig>()
    .HasIndex(pc => new {pc.Category, pc.Product})
        .IsUnique();

有关详细信息,请阅读:HasIndex - Fluent API

编辑2 (获取信息解决方案后适用于EF&lt; 6.2

在上一次编辑问题之后,需要采用另一种解决方案。 我们走了......

您需要一个如下所示的结构:

<强>产品

public class Product
{
    // other properties

    public virtual ICollection<ProductConfig> ProductConfigs { get; set; }
}

<强>分类

public class Category
{
    // other properties

    public virtual ICollection<ProductConfig> ProductConfigs { get; set; }
}

<强> ProductConfig

public class ProductConfig
{
    // other properties

   public virtual Category { get; set; }

   public virtual Product { get; set; }

   public virtual ProductCategoryType { get; set; }
}

在EF&lt;中设置唯一约束。 6.2你必须这样做:

modelBuilder.Entity<ProductConfig>()
        .Property(e => e.Category)
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(new IndexAttribute("YourIndex", 1) { IsUnique = true }));

modelBuilder.Entity<ProductConfig>()
        .Property(e => e.Product)
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(new IndexAttribute("YourIndex", 2) { IsUnique = true }));

modelBuilder.Entity<ProductConfig>()
        .Property(e => e.ProductCategoryType)
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(new IndexAttribute("YourIndex", 3) { IsUnique = true }));
EF 6.2中的

modelBuilder.Entity<Person>()
    .HasIndex(p => new { p.Category, p.Product, p.ProductCategoryType })
    .IsUnique();

编辑3 如果您的ProductConfig类中没有主键,或者您在我没有添加的示例中使用了我的主键,因为我认为您已经拥有该类。 可以将多个属性设置为键。这也将产生独特的组合。 您可以使用以下内容对其进行归档 - 而不是索引内容:

modelBuilder.Entity<ProductConfig>()
            .HasKey(pc => new { pc.Category, pc.Product, pc.ProductCategoryType });

有关详细信息,请查看MS docs

您还可以添加Id作为主键,而不是索引。