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

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

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

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

在插入之前,EF 会创建临时 ID,这些临时 ID 将被替换为真实的数据库 ID。

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

Key (\"ID\")=(5) already exists

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

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

我试过添加属性

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

尝试更改 DbContext

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

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

我还找到了this Microsoft 文档中的文章说

If the graph does contain duplicates, then it will be necessary to process the graph before sending it to EF to consolidate multiple instances into one.

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

我这样做是错误的还是在 EF Core 2.2 中不可能?

最佳答案

魔术酱:创建一个接口(interface)并在您不想保存在对象图上的对象上实现它,然后不要将该对象设置为已修改。我未能理解的范例是,当该对象用于定义要保存的对象时,我从未真正想在保存期间保存该对象。

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

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;
    }

https://stackoverflow.com/questions/57267385/

相关文章:

html - 如何修复内容安全策略错误?

python - 如何使用分类变量和数值变量绘制相关矩阵/热图

typescript - VS代码/w。在 TypeScript Monorepo 中更漂亮

spring - 让 Spring RestTemplate 使用内存中的 pem 证书(不在磁盘上

google-cloud-storage - 与 Google Cloud Storage 的连接池

python-3.x - 属性错误 : 'NoneType' object has no attri

flutter - flutter 的 video_playeur 包问题

svelte - 将选定的 Svelte 组件编译为 CustomElements

asp.net-core-2.0 - 如何在 .net 核心 web api 中将 Razor Vi

django - 自定义 Django Admin 用户密码修改表单