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

本文关键字:删除 实体 EF 分离 为什么 | 更新日期: 2023-09-27 17:57:02

我需要做一些类似的事情...

  1. 获取数据库上下文(实用程序上下文)
  2. 查询它以获取某些数据(监视目录)
  3. 当我拉WD时,也从数据库中提取孩子(附加数据)
  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 在分离时会删除子实体

EF

是一个有趣的野兽,这是将实体从上下文中分离的终极治疗方法......

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

可能对此有更好的做法,但这种牛在中国商店的方法解决了我的问题。

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

您序列化某些内容以

反序列化某些内容的方法是一种糟糕的 DTO 方法。应执行映射(可能使用自动映射程序),或关闭 EF 代理处理和延迟加载,这具有类似的效果。