具有可选关系的实体拆分 - (EF代码优先)

时间:2013-05-21 21:44:55

标签: entity-framework orm ef-code-first entity-framework-4.1

我有2个表:Orders表和OrderActivity表。如果订单未进行任何活动,则OrderActivity表中将没有记录。我目前将OrderActivity表映射为Order实体上的可选nav属性,并且我处理对OrderActivity的更新,如下所示:

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

是否可以合并这样,使OrderActivity表的列映射到Orders实体上的属性,并且如果没有OrderActivity记录,则默认为?仅当两个表中都存在记录时,实体拆分的配置才会起作用。如果不可能,那么从我的域模型中隐藏子实体的最佳做法是什么?我的目标是在与我无法控制的数据库模式交互时尽可能保持模型的清洁。

1 个答案:

答案 0 :(得分: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将具有值或为null。

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