【问题标题】:Saving Entity causes duplicate insert into lookup data保存实体会导致重复插入查找数据
【发布时间】:2011-04-15 11:01:12
【问题描述】:

我使用 EF 4.1“代码优先”来创建我的数据库和对象。

给定:

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

public class OrderType 
{
    public int Id { get; set; }
    public string Name { get; set; }
}

一个订单有一个订单类型。订单类型只是一个查找表。值不会改变。使用 Fluent API:

//Order
ToTable("order");
HasKey(key => key.Id);
Property(item => item.Id).HasColumnName("order_id").HasColumnType("int");
Property(item => item.Name).HasColumnName("name").HasColumnType("string").HasMaxLength(10).IsRequired();

HasRequired(item => item.OrderType).WithMany().Map(x => x.MapKey("order_type_id")).WillCascadeOnDelete(false);

//OrderType
ToTable("order_type");
HasKey(key => key.Id);

Property(item => item.Id).HasColumnName("order_type_id").HasColumnType("int");
Property(item => item.Name).HasColumnName("name").HasColumnType("nvarchar").HasMaxLength(100).IsRequired(); 

现在在我们的应用程序中,我们加载所有查找数据并将其缓存。

var order = new Order
{
   Name = "Bob"
   OrderType = GetFromOurCache(5) //Get order type for id 5
};

var db = _db.GetContext();
db.Order.Add(order);
db.SaveChanges();

我们的 you-beaut 订单已保存,但有一个新的订单类型,由 EF 提供。所以现在我们的数据库中有两个相同的订单类型。我可以做些什么来改变这种行为?

TIA

【问题讨论】:

    标签: c# entity-framework-4 ef-code-first entity-framework-4.1


    【解决方案1】:

    使用 EF 4.1,您可以在调用 SaveChanges 之前执行此操作:

    db.Entry(order.OrderType).State = EntityState.Unchanged;
    

    【讨论】:

      【解决方案2】:

      作为 Yakimych 解决方案的替代方案,您可以在添加订单之前将 OrderType 附加到上下文中,让 EF 知道 OrderType 已经存在于数据库中:

      var order = new Order
      {
          Name = "Bob"
          OrderType = GetFromOurCache(5) //Get order type for id 5
      };
      
      var db = _db.GetContext();
      db.OrderTypes.Attach(order.OrderType);
      db.Order.Add(order);
      db.SaveChanges();
      

      【讨论】:

        【解决方案3】:

        Yakimych / Slauma - 感谢您的回答。有趣的是,我尝试了两种方法,但都没有奏效。因此我问了这个问题。您的回答证实我一定做错了什么,果然我没有正确管理我的 dbContext。

        即使您提供完整的对象(包括查找唯一 ID),EF 仍会自动插入查找/静态数据,这仍然很痛苦。它使开发人员有责任记住设置状态。为了让事情变得更容易,我这样做:

        var properties = entry.GetType().GetProperties().Where(x => x.PropertyType.GetInterface(typeof(ISeedData).Name) != null);
        foreach (var staticProperty in properties)
        {
            var n = staticProperty.GetValue(entry, null);
            Entry(n).State = EntityState.Unchanged;
        }  
        

        在 SaveChanges 覆盖中。

        再次感谢您的帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-23
          • 2015-01-17
          • 1970-01-01
          • 1970-01-01
          • 2019-10-18
          • 1970-01-01
          • 1970-01-01
          • 2012-03-10
          相关资源
          最近更新 更多