复合密钥实体,不想声明 PK 密钥
Composite key entity and dont want to declare PK keys
好的,这应该很简单。我有一个class
public class ProductConfig
{
public Category { get;set; }
public Product { get;set; }
}
这两个导航属性也是 table 的主键。
声明 PRoductId 和 CategoryIds 是多余的。如何使用导航属性配置主键?
编辑:愚蠢的我。我在上面的问题中忘记了一些非常重要的事情。上面那两个是指出配置。然后我们有第三个 fk,那就是为产品和类别的组合选择的配置。所以上面的实体必须是物化实体
public class ProductConfig
{
public Category { get;set; }
public Product { get;set; }
public ProductCategoryType { get; set; }
}
您只需通过导航属性设置产品和类别实体之间的关系。 EF 将自己设置正确的 table 结构作为 many-to-many 关系。所以不需要自己的关系实体。
请检查一下:many-to-many-relationship in EF
例如:
产品class:
public class Product
{
// other properties
public virtual ICollection<Category> Categories { get; set; }
}
类别class:
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; }
}
产品配置
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 class 中没有主键,或者您在我添加 none 的示例中使用了我的主键,因为我认为您已经有了 class。
可以将多个属性设置为键。这也会产生独特的组合。
您将使用以下内容存档 - 而不是索引内容:
modelBuilder.Entity<ProductConfig>()
.HasKey(pc => new { pc.Category, pc.Product, pc.ProductCategoryType });
有关更多信息,请查看 MS docs。
您还可以添加一个 Id 作为主键,而不是需要索引。
Declaring ProductId and CategoryId are redundant. How can get configure the primary keys using the nav properties?
很快 - 你不能。虽然 EF6 支持基于 shadow 属性 的 FK,但它不提供使用 shadow 属性 名称 - [Key]
、[=11= 配置 PK(以及许多其他列相关设置)的方法]数据注释不能应用于导航 属性 和 HasKey
流畅 API 需要原始 属性 选择器表达式。一般EF6不支持PK中的shadow属性。
所有这些限制都已在 EF Core 中移除。但在 EF6 中,无论冗余与否,您必须定义实体中的实际原始属性并将它们映射到复合 PK。
好的,这应该很简单。我有一个class
public class ProductConfig
{
public Category { get;set; }
public Product { get;set; }
}
这两个导航属性也是 table 的主键。 声明 PRoductId 和 CategoryIds 是多余的。如何使用导航属性配置主键?
编辑:愚蠢的我。我在上面的问题中忘记了一些非常重要的事情。上面那两个是指出配置。然后我们有第三个 fk,那就是为产品和类别的组合选择的配置。所以上面的实体必须是物化实体
public class ProductConfig
{
public Category { get;set; }
public Product { get;set; }
public ProductCategoryType { get; set; }
}
您只需通过导航属性设置产品和类别实体之间的关系。 EF 将自己设置正确的 table 结构作为 many-to-many 关系。所以不需要自己的关系实体。 请检查一下:many-to-many-relationship in EF
例如:
产品class:
public class Product
{
// other properties
public virtual ICollection<Category> Categories { get; set; }
}
类别class:
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; }
}
产品配置
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 class 中没有主键,或者您在我添加 none 的示例中使用了我的主键,因为我认为您已经有了 class。 可以将多个属性设置为键。这也会产生独特的组合。 您将使用以下内容存档 - 而不是索引内容:
modelBuilder.Entity<ProductConfig>()
.HasKey(pc => new { pc.Category, pc.Product, pc.ProductCategoryType });
有关更多信息,请查看 MS docs。
您还可以添加一个 Id 作为主键,而不是需要索引。
Declaring ProductId and CategoryId are redundant. How can get configure the primary keys using the nav properties?
很快 - 你不能。虽然 EF6 支持基于 shadow 属性 的 FK,但它不提供使用 shadow 属性 名称 - [Key]
、[=11= 配置 PK(以及许多其他列相关设置)的方法]数据注释不能应用于导航 属性 和 HasKey
流畅 API 需要原始 属性 选择器表达式。一般EF6不支持PK中的shadow属性。
所有这些限制都已在 EF Core 中移除。但在 EF6 中,无论冗余与否,您必须定义实体中的实际原始属性并将它们映射到复合 PK。