EF Core - 无法添加具有相同相关对象的实体

Posted

技术标签:

【中文标题】EF Core - 无法添加具有相同相关对象的实体【英文标题】:EF Core - can't add entity with the same related objects 【发布时间】: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,很遗憾没有 我想通了.. 解决方案是不保存那种类型的对象! :) 【参考方案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

以上是关于EF Core - 无法添加具有相同相关对象的实体的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 过滤掉多对多关系中的重复实体

EF Core 处理相同的实体,但一个是空的,一个不是

使用 EF Core 保存附加实体时如何删除子实体

ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象

如何将同一列添加到 EF Core 中的所有实体?

EF Core选择由相关实体过滤的一个实体