2011-04-15 112 views
2

我使用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(); 

我们您-BEAUT订单保存但新的订单类型,EF的礼貌。所以现在我们的数据库中有两个相同的订单类型。我能做些什么来改变这种行为?

TIA

回答

6

随着EF 4.1,你可以在调用SaveChanges之前:

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

或者到Yakimych的解决方案,您可以附加的订单类型上下文你加为了让EF才知道该订单类型已存在于数据库:

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(); 
0

Yakimych/SL auma - 感谢您的答案。有趣的是,我尝试了两种方式,都没有奏效。因此我问了这个问题。你的答案证实我必须做错了什么,果然我没有正确地管理我的dbContext。

即使提供完整对象(包括查找唯一标识),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; 
} 

in SaveChanges override。

再次感谢您的帮助。