[英]composite key as foreign key
I am using Entity framework 4.1 in MVC 3 application.我在 MVC 3 应用程序中使用实体框架 4.1。 I have an entity where I have primary key consists of two columns ( composite key).
我有一个实体,其中我的主键由两列(复合键)组成。 And this is being used in another entity as foreign key.
这在另一个实体中用作外键。 How to create the relationship?
如何建立关系? In normal scnerios we use:
在正常场景中,我们使用:
public class Category
{
public string CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
but what if category has two columns key?但是如果类别有两列键怎么办?
You can use either fluent API: 您可以使用任何一种流畅的API:
public class Category
{
public int CategoryId1 { get; set; }
public int CategoryId2 { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public int CategoryId1 { get; set; }
public int CategoryId2 { get; set; }
public virtual Category Category { get; set; }
}
public class Context : DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Category>()
.HasKey(c => new {c.CategoryId1, c.CategoryId2});
modelBuilder.Entity<Product>()
.HasRequired(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => new {p.CategoryId1, p.CategoryId2});
}
}
Or data annotations: 或数据注释:
public class Category
{
[Key, Column(Order = 0)]
public int CategoryId2 { get; set; }
[Key, Column(Order = 1)]
public int CategoryId3 { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product
{
[Key]
public int ProductId { get; set; }
public string Name { get; set; }
[ForeignKey("Category"), Column(Order = 0)]
public int CategoryId2 { get; set; }
[ForeignKey("Category"), Column(Order = 1)]
public int CategoryId3 { get; set; }
public virtual Category Category { get; set; }
}
I believe the easiest way is to use Data Annotation on the Navigation property like this: [ForeignKey("CategoryId1, CategoryId2")]
我相信最简单的方法是在Navigation属性上使用Data Annotation,如下所示:
[ForeignKey("CategoryId1, CategoryId2")]
public class Category
{
[Key, Column(Order = 0)]
public int CategoryId1 { get; set; }
[Key, Column(Order = 1)]
public int CategoryId2 { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product
{
[Key]
public int ProductId { get; set; }
public string Name { get; set; }
public int CategoryId1 { get; set; }
public int CategoryId2 { get; set; }
[ForeignKey("CategoryId1, CategoryId2")]
public virtual Category Category { get; set; }
}
In .NET Core
and .NET 5 <
the documentation only shows Data annotations (simple key)
.在
.NET Core
和.NET 5 <
文档中只显示了Data annotations (simple key)
。
https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-composite-key%2Csimple-key#foreign-key https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-composite-key%2Csimple-key#foreign-key
However using the example from @LadislavMrnka you will get a error message like this:但是使用来自@LadislavMrnka 的示例,您将收到如下错误消息:
System.InvalidOperationException: There are multiple properties with the [ForeignKey] attribute pointing to navigation ''.
System.InvalidOperationException:有多个 [ForeignKey] 属性指向导航“”的属性。 To define a composite foreign key using data annotations, use the [ForeignKey] attribute on the navigation.
要使用数据注释定义复合外键,请在导航中使用 [ForeignKey] 属性。
Using that error message you can write the code like this:使用该错误消息,您可以编写如下代码:
public class Product
{
[Key]
public int ProductId { get; set; }
public string Name { get; set; }
public int CategoryId2 { get; set; }
public int CategoryId3 { get; set; }
[ForeignKey("CategoryId2,CategoryId3")]
public virtual Category Category { get; set; }
}
Fluent API (composite key)
example from Microsoft:来自 Microsoft 的
Fluent API (composite key)
示例:
internal class MyContext : DbContext
{
public DbSet<Car> Cars { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasKey(c => new { c.State, c.LicensePlate });
modelBuilder.Entity<RecordOfSale>()
.HasOne(s => s.Car)
.WithMany(c => c.SaleHistory)
.HasForeignKey(s => new { s.CarState, s.CarLicensePlate });
}
}
public class Car
{
public string State { get; set; }
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public List<RecordOfSale> SaleHistory { get; set; }
}
public class RecordOfSale
{
public int RecordOfSaleId { get; set; }
public DateTime DateSold { get; set; }
public decimal Price { get; set; }
public string CarState { get; set; }
public string CarLicensePlate { get; set; }
public Car Car { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.