【问题标题】:EF Core - can't add entity with the same related objectsEF Core - 无法添加具有相同相关对象的实体
【发布时间】:2019-12-07 14:14:31
【问题描述】:

我正在将应用程序从 EF 6 移植到 EF Core 2.2。我有一个对象,里面有一些相关的对象,每个对象都有数据库生成的 ID 和 GUID(db - postgresql)。

我正在尝试创建一个通用方法,以与 EF 6 中相同的方式添加具有所有相关对象的整个对象图 - 如下所示:

var res = context.Set<T>().Add(entity);

在插入之前,EF 制作临时 ID,将替换为真实的数据库 ID。

所以,因为在不同的对象中我可能有完全相同的对象(为了更好地理解,我的主题领域是医学,我有几个不同的分析是从同一个样本中执行的),在 EF Core 中我不能添加整个像这样的对象图 - 出现错误,例如:

键 (\"ID\")=(5) 已存在

但在 EF 6 版本中,一切都正常工作 - 所有对象都被插入,包括具有正确 ID 和 GUID 的内部对象,没有重复。

在两个版本中,相同对象中的临时 ID 也相同,但仅在 EF Core 版本中,我收到此错误。

我试过添加属性

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

尝试更改DbContext

modelBuilder.Entity<Sample>().Property(e => e.ID).ValueGeneratedOnAdd();

但两者都不适合我 - 我认为问题不在这里。

我还在 Microsoft 文档中找到了 this 文章,上面写着

如果图表确实包含重复项,则需要在将图表发送到 EF 之前对其进行处理,以将多个实例合并为一个。

但我不确定 - 这是关于我的情况吗?

这是我做错了还是在 EF Core 2.2 中不可能?

【问题讨论】:

  • 我和你一起进入这个噩梦。你弄明白了吗?
  • @CarComp,很遗憾没有
  • 我想通了.. 解决方案是不保存那种类型的对象! :)

标签: c# postgresql entity-framework entity-framework-core


【解决方案1】:

魔术酱:创建一个接口并在您不想保存在对象图上的对象上实现它,然后简单地不要将该对象设置为已修改。我无法理解的范例是,当使用该对象定义要保存的对象时,我从来没有真正想在保存期间保存“定义”对象。

我使用单独的过程保存定义对象。完美运行。

public virtual T InsertOrUpdate(T oneObject)
    {
        T output = null;

        if (oneObject.Id == Guid.Empty)
        {
            output = this.Insert(oneObject);
        }
        else
        {
            try
            {
               
                _dbContext.ChangeTracker.TrackGraph(oneObject, e =>
                {
                    if (e.Entry.IsKeySet)
                    {
                        // See if the entry has interface with 'StaticObject'
                        List<Type> x = e.Entry.Entity.GetType().GetInterfaces().ToList();
                        
                        if (x.Contains(typeof(IStaticObject)))
                        {
                            _logger.LogWarning($"Not tracking entry {e.Entry}");
                        }
                        else
                        {
                            e.Entry.State = EntityState.Modified;
                        }
                    }
                    else
                    {
                        e.Entry.State = EntityState.Added;
                    }

                });

                _dbContext.Entry(oneObject).State = EntityState.Modified;

                _dbContext.SaveChanges();
                
                output = oneObject;
                
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Problem updating object {oneObject.Id}");
            }
        }

        return output;
    }
    
public virtual T Insert(T oneObject)
    {
        try
        {
            _dbContext.Attach(oneObject);
            _dbContext.Entry(oneObject);
            _dbContext.SaveChanges();
        }
        catch (Exception error)
        {
            _logger.LogError(error.Message, error);
        }

        return oneObject;
    }

【讨论】:

  • if (e.Entry.Entity is IStaticObject) ?
  • 哦。我知道了。我只是使用包含。在阵列上使用时,我还没有完全信任 Is
猜你喜欢
  • 2018-02-12
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2020-09-04
相关资源
最近更新 更多