复合键实体并且不想声明PK键

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复合键实体并且不想声明PK键相关的知识,希望对你有一定的参考价值。

好的,这应该很简单。我上课了

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

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

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

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

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

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

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

另一答案

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

e.f.:

产品类别:

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 <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 <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作为主键,而不是索引。

以上是关于复合键实体并且不想声明PK键的主要内容,如果未能解决你的问题,请参考以下文章

如何进行 Hibernate XML 映射,一对多使用 1 PK 映射到另一个具有复合键的实体

使用未映射的列映射复合键

Spring用外键保存复合主键

EF 代码优先 - 配置一对零或一关系,无需共享 PK/FK

实体框架代码优先迁移忽略 [Key] 并强制复合键

Fluent NHibernate 多对多映射,使用自动生成的 pk 而不是复合键