2011-04-15 114 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。

再次感謝您的幫助。