为什么 EF 在分离时删除子实体?

Why does EF remove child entities when detaching?

我需要做类似...

  1. 获取数据库上下文 (UtilitiesContext)
  2. 查询一些数据(监视目录)
  3. 当我拉出 WD 的 (AdditionalData) 时,也从数据库中拉出子节点
  4. 处理上下文
  5. 继续使用实体

...

// step 1
using (var db = new UtilitiesContext(false))
{
    var jsonSettings = new JsonSerializerSettings { MaxDepth = 2, ReferenceLoopHandling = ReferenceLoopHandling.Ignore };

    // step 2
    var dirs = db.GetAll<WatchedDirectory>();

    // step 3 (lazy load and serialize the WD and its additional data)
    log.Debug(JsonConvert.SerializeObject(dirs, jsonSettings));

    foreach (var d in dirs)
    {
        try
        {
            log.Debug("    Initialising monitoring for path " + d.UNCPath);

            // detach the object and its data items from the db
            db.Detach(d);
            d.AdditionalData.ForEach(i => db.Detach(i));

            // here the AdditionalData property serialises an empty array
            log.Debug(JsonConvert.SerializeObject(d, jsonSettings));

// step 4 happens down here

我的问题是我在第一个日志输出中得到了我想要的所有数据(标记为第 3 步的行) 然后当我重复说子集合已经消失时,我所做的只是从上下文中分离实体。

我的分离方法如下所示...

public void Detach(object entity)
{
    Entry(entity).State = EntityState.Detached;
}

EF 是一只有趣的野兽,这是将实体从上下文中分离出来的终极良方...

var jsonSettings = new JsonSerializerSettings { MaxDepth = 2, ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
var dirs = JsonConvert.DeserializeObject<List<WatchedDirectory>>(JsonConvert.SerializeObject(db.GetAll<WatchedDirectory>().ToList(), jsonSettings));

这方面可能有更好的做法,但这种 bull in china shop 方法解决了我的问题。

当您从上下文中分离 parent 实体时,您不能再使用 child 实体的延迟加载(在您的情况下,无论如何您都不应该这样做,b/c性能将受到很大影响)。性能更高的方法是使用 includes() 预先加载所需的 children。这将为您节省对数据库的额外调用。例如,如果每个 parent 有 2 个 children,您将对 parent 进行 1 次调用,并对每个 child 进行额外的 2 次调用。效率很低。

你序列化某些东西以反序列化某些东西的方法是一种糟糕的获取 DTO 的方法。您应该进行映射(可能使用 Automapper),或者关闭 EF 代理处理和延迟加载,这具有类似的效果。