【问题标题】:How to set default values for foreign keys in Entity Framework code-first models如何在实体框架代码优先模型中为外键设置默认值
【发布时间】:2013-08-07 10:20:32
【问题描述】:

我正在使用 Entity Framework 5,代码优先。

我有一个如下所示的 POCO:

public class Order
{
  public int Id { get; set; }
  public string Name { get; set; }
  public virtual Status Status { get; set; }

  public Order()
  {
    this.Status = new Status() { Id = 1 }
  }
}

这被流畅地映射为:

public class OrderMap : EntityTypeConfiguration<Order>
{
  public OrderMap()
  {
    ToTable("Order");
    HasKey(x => x.Id);

    Property(x => x.Id);
    Property(x => x.Name).IsRequired();

    HasRequired(x => x.Status)
      .WithMany(x => x.Orders)
      .Map(x => x.MapKey("StatusId"));
  }
}

在数据库中,Order 表的默认值StatusId 设置为1

但是,当添加一个新的Order 时,我得到了这个错误:

违反 PRIMARY KEY 约束“Status_PK”。无法插入 对象“dbo.Status”中的重复键。重复键值为 (1)

如果我在 Order ctor 中删除对 Status 的分配,那么我会得到这个:

无法将值 NULL 插入列“StatusId”,表 'MyDatabase.dbo.Order';列不允许空值。插入失败

如何设置外键属性的默认值?

【问题讨论】:

    标签: entity-framework orm entity-framework-5


    【解决方案1】:

    通过构造函数为订单提供默认状态(否则将插入新状态,因为整个图形将处于已添加状态):

    public class Order
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual Status Status { get; set; }
    
        public Order(Status initialtStatus)
        {
            Status = initialtStatus;
        }
    }
    

    并像这样使用它:

    var status = db.Statuses.Find(1);
    var order = new Order (status) { Name = "Lazy" };
    db.Orders.Add(order);
    db.SaveChanges();
    

    更新:另一个选项是将默认状态实体附加到上下文或手动设置它的状态:

    var order = new Order { Name = "Lazy" };
    db.Entry(order.Status).State = EntityState.Unchanged; // avoid inserting
    db.Orders.Add(order);
    db.SaveChanges();    
    

    【讨论】:

    • 我提供的示例中没有插入新状态。如果可能的话,我也宁愿在实例化新的 Order 对象以提供状态时不必使用数据上下文......它只是感觉不对。每次都有代码在ctor中提供它也是一个PITA(我没有提到应用程序中的几乎每个POCO都需要使用Status来执行此操作!)
    • @Cocowalla 实际上应该插入它。如果您要检查更改跟踪器中条目的状态,状态将与订单具有相同的状态 - 它将是 Added。因此将为状态生成插入查询
    • 但我只收到Cannot insert the value NULL into column 'StatusId', table 'MyDatabase.dbo.Status'; column does not allow nulls. INSERT fails
    • @Cocowalla 刚刚验证 - 使用您提供的代码我没有这个例外。无论如何 - 我添加了另一个选项以避免插入状态。您也可以使用StatusId 属性而不是Status 实体(但我认为这不是最佳解决方案)
    • 我知道...只是说:)
    猜你喜欢
    • 2013-03-07
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    相关资源
    最近更新 更多