2013-05-21 76 views
0

我有2個表:Orders表和OrderActivity表。如果訂單上沒有任何活動,則OrderActivity表中不會有記錄。我現在有映射爲對Order實體的可選導航屬性OrderActivity表,我處理更新OrderActivity這樣的:實體拆分與可選關係 - (EF代碼優先)

if (order.OrderActivity == null) 
{ 
    order.OrderActivity = new OrderActivity(); 
} 
order.OrderActivity.LastAccessDateTime = DateTime.Now; 

是否有可能合併這使得OrderActivity表的列映射到屬性在Orders實體上,如果沒有OrderActivity記錄,會默認?如果兩個表中都存在記錄,則實體拆分配置似乎只能工作。如果這是不可能的,那麼最好的做法是將我的域模型中的子實體隱藏起來?我的目標是保持模型儘可能乾淨,同時與我無法控制的數據庫模式交互。

+0

你的意思是你想阻止你的客戶端代碼訪問order.OrderActivity? –

+0

基本上是... order.OrderActivity提供的唯一的事情是LastAccessDateTime,所以我想扁平化這兩個對象並將LastAccessDateTime屬性視爲Order的一部分。我知道這可以通過映射實體到不同的表,但我可以這樣做,如果有時不會有DB中的OrderActivity記錄 – Eric

+0

您可以做到這一點,但總是會有OrderActivity中的值與LastAccessDate值或空。看到我的答案,如果有幫助。 –

回答

0

您可以創建映射並將LastAccessDate的類型指定爲Nullable<DateTime>。該映射將與LastAccessDate是可選的創建一對一。

public class Order { 
    [Key] 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public DateTime? LastAccessDate { get; set; } 
} 

modelBuilder.Entity<Order>().Map(m => { 
      m.Properties(a => new { a.Id, a.Name }); 
      m.ToTable("Order"); 
     }).Map(m => { 
      m.Properties(b => new { b.Id, b.LastAccessDate }); 
      m.ToTable("OrderActivity"); 
     }); 

在這種情況下,在插入新訂單時指定LastAccessDate屬性是可選的。

var order = new Order(); 
order.Name = "OrderWithActivity"; 
order.LastAccessDate = DateTime.Now; 
db.Orders.Add(order); 
db.SaveChanges(); 

order = new Order(); 
order.Name = "OrderWithoutActivity"; 
db.Orders.Add(order); 
db.SaveChanges(); 

注意這將始終在每個表中創建一個條目。這是必要的,因爲EF在您檢索訂單時創建INNER JOIN,並且您希望在此情況下獲得所有訂單。 LastAccessDate將具有值或爲空。

// Gets both orders 
var order = db.Orders.ToList(); 
// Gets only the one with activity 
var orders = db.Orders.Where(o => o.LastAccessDate != null);