【问题标题】:How to Specify a Compound key in Entity Framework Code First如何首先在实体框架代码中指定复合键
【发布时间】:2011-05-08 17:09:49
【问题描述】:

我有一个关于在 Northwind 数据库中设置 [Order Details][Products][Orders] 之间的映射的快速问题。

[Order Details] 没有主键,看起来像这样

[Order Details]
OrderId (int)
ProductId (int)
...

所以我的问题是我如何(并且我可以)设置我的OrderDetails 类以这样的方式工作?

public class OrderDetails
{
    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
    public Decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
    public Decimal Discount { get; set; }
}

我的数据上下文如下所示

public class NorthwindDb : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetails> OrderDetails { get; set; }
    public DbSet<Customer> Customers { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new OrderDetailsConfiguration());
    }

    public static void InitializeBecauseOfThatWeirdMetaDataThingThatIDontUnderstandYet()
    {
        Database.SetInitializer<NorthwindDb>(null);
    }

}

还有我的OrderDetailsConfiguration(空着,因为我不知道自己在做什么)

public class OrderDetailsConfiguration : EntityConfiguration<OrderDetails>
{
    public OrderDetailsConfiguration()
    {
        //HasKey(x => x.Order.OrderId);
        //HasKey(x => x.Product.ProductId);
    }
}

任何提示或想法都会很棒。

【问题讨论】:

    标签: entity-framework-4 poco code-first northwind


    【解决方案1】:

    首先,您必须在 OrderDetails 类中明确放入 PK 和 FK:

    public class OrderDetails 
    {        
        public int OrderID { get; set; }
        public int ProductID { get; set; }
    
        public virtual Order Order { get; set; }
        public virtual Product Product { get; set; }
    
        public Decimal UnitPrice { get; set; }
        public int Quantity { get; set; }
        public Decimal Discount { get; set; }
    }
    

    然后,您可以使用以下代码为 OrderDetailsConfiguration 类指定 PK:
    (请注意,在 Northwind 数据库中,OrderIDProductID 都是 OrderDetails 表的 PK。

    public class OrderDetailsConfiguration : EntityConfiguration<OrderDetails> 
    {
        public OrderDetailsConfiguration() 
        {
            HasKey(od => new 
            {
                od.ProductID,
                od.OrderID
            });
        }
    }
    

    您还可以使用 RecreateDatabaseIfModelChanges 策略来强制每次更改类模型时重新创建数据库:

    Database.SetInitializer<NorthwindDb>(
            new RecreateDatabaseIfModelChanges<NorthwindDb>());
    

    有趣的是,一旦您进行了这些更改,EF 将自动从 OrderDetails 类推断 FK,并创建与 OrdersProducts 的关系> 基于Conventions for Code First: 的OrderID 和ProductID 表

    Code First 将推断任何名为 &lt;navigation property name&gt;&lt;primary key property name&gt;(即 ProductsProductID)、&lt;principal class name&gt;&lt;primary key property name&gt;(即 ProductProductID)或 &lt;primary key property name&gt;(即 ProductID)的属性与主键具有相同的数据类型,表示关系。如果找到多个匹配项,则按上面列出的顺序给出优先级。外键检测不区分大小写。

    【讨论】:

    • 感谢您的帮助,莫特萨。我想下一个问题是如何保护订单和产品 id,但我会在问这里之前做一些挖掘。
    • 没问题,我很高兴它有帮助:)
    【解决方案2】:

    用 [Key] 属性标记关键字段。如果是复合键,则需要添加 [Column(Order = x)],x = 0, 1, 2, ... 编号可以从任何数字开始 https://msdn.microsoft.com/en-us/data/jj591583.aspx

    【讨论】:

      猜你喜欢
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多