C# EF Core-插入然后更新条目

C# EF Core-插入然后更新条目,c#,entity-framework-core,asp.net-core-webapi,C#,Entity Framework Core,Asp.net Core Webapi,在一个WebApi方法中,如果一个元素不存在,我需要插入它并在一些操作之后更新它 代码如下: Entry existingEntry = await _repo.GetEntryByIdAsync(id); existingEntry = await _repo.AddNewEntryAsync(existingAccred); // Some code... // Update existingAccred.IdField = myField; await _repo.UpdateEnt

在一个WebApi方法中,如果一个元素不存在,我需要插入它并在一些操作之后更新它

代码如下:

Entry existingEntry = await _repo.GetEntryByIdAsync(id);

existingEntry = await _repo.AddNewEntryAsync(existingAccred);

// Some code...

// Update
existingAccred.IdField = myField;
await _repo.UpdateEntryAsync(existingEntry);
    public async Task<Entry> GetEntryByIdAsync(int myId)
    {
        var result = from entry in _ctx.Set<DALENTRY>()
            where entry.ID == myId
            select new Entry
            {
                ID = entry.IdEntry,
            };

        return await result.AsNoTracking().FirstOrDefaultAsync();
    }

    public async Task<Entry> AddNewEntryAsync(Entry newEntry)
    {
        DALENTRY entry = new DALENTRY()
        {
            GUID = newEntry.GUID,
        };

        _ctx.Add(entry);
        await _ctx.SaveChangesAsync();

        newEntry.IdEntry = entry.ID;

        return newEntry;
    }

    public async Task<Entry> UpdateEntryAsync(Entry updateEntry)
    {
        DALENTRY entry = new DALENTRY()
        {
            ID = updateEntry.IdEntry,
            FIELD= updateEntry.IdField,
        };

        _ctx.Update(entry);
        await _ctx.SaveChangesAsync();

        return updateEntry;
    }
回购协议如下:

Entry existingEntry = await _repo.GetEntryByIdAsync(id);

existingEntry = await _repo.AddNewEntryAsync(existingAccred);

// Some code...

// Update
existingAccred.IdField = myField;
await _repo.UpdateEntryAsync(existingEntry);
    public async Task<Entry> GetEntryByIdAsync(int myId)
    {
        var result = from entry in _ctx.Set<DALENTRY>()
            where entry.ID == myId
            select new Entry
            {
                ID = entry.IdEntry,
            };

        return await result.AsNoTracking().FirstOrDefaultAsync();
    }

    public async Task<Entry> AddNewEntryAsync(Entry newEntry)
    {
        DALENTRY entry = new DALENTRY()
        {
            GUID = newEntry.GUID,
        };

        _ctx.Add(entry);
        await _ctx.SaveChangesAsync();

        newEntry.IdEntry = entry.ID;

        return newEntry;
    }

    public async Task<Entry> UpdateEntryAsync(Entry updateEntry)
    {
        DALENTRY entry = new DALENTRY()
        {
            ID = updateEntry.IdEntry,
            FIELD= updateEntry.IdField,
        };

        _ctx.Update(entry);
        await _ctx.SaveChangesAsync();

        return updateEntry;
    }
public异步任务GetEntryByIdAsync(int myId)
{
var result=来自_ctx.Set()中的条目
其中entry.ID==myId
选择新条目
{
ID=entry.IdEntry,
};
返回wait result.AsNoTracking().FirstOrDefaultAsync();
}
公共异步任务AddNewEntryAsync(条目newEntry)
{
DALENTRY条目=新的DALENTRY()
{
GUID=newEntry.GUID,
};
_ctx.Add(条目);
wait_ctx.saveChangesSync();
newEntry.IdEntry=entry.ID;
返回新条目;
}
公共异步任务UpdateEntryAsync(条目updateEntry)
{
DALENTRY条目=新的DALENTRY()
{
ID=updateEntry.IdEntry,
FIELD=updateEntry.IdField,
};
_ctx.更新(条目);
wait_ctx.saveChangesSync();
返回更新尝试;
}
但当我执行更新时,得到的是以下错误:

处理请求时发生未处理的异常

InvalidOperationException:无法创建实体类型“DALENTRY”的实例 无法跟踪,因为具有相同键值的另一个实例 {ID'}已被跟踪。在附加现有实体时, 确保只创建一个具有给定键值的实体实例 附属的。考虑使用 “DbContextOptions Builder.EnableSensivedAtalogging”以查看 相互冲突的键值。 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.Add(TKey 键,InternalEntityEntry)

回购被登记为暂时性的,如:

services.AddTransient<EntryRepository>();
services.AddTransient();

我尝试在插入后使用Detach,但使用它更新会清除所有未更新的字段。我不记得是什么导致了这个问题。

通过先读取条目,然后更新条目,解决了在回购协议中更改更新策略的问题:

public async Task<Entry> UpdateEntryAsync(Entry updateEntry)
{
    DALENTRY entry = await _ctx.Set<DALENTRY >().SingleOrDefaultAsync(a => a.ID == updateEntry.IdEntry);

    entry.FIELD= updateEntry.IdField,

    _ctx.Update(entry);
    await _ctx.SaveChangesAsync();

    return updateEntry;
}
public异步任务UpdateEntryAsync(条目updateEntry)
{
DALENTRY entry=await _ctx.Set().SingleOrDefaultAsync(a=>a.ID==updateEntry.IdEntry);
entry.FIELD=updateEntry.IdField,
_ctx.更新(条目);
wait_ctx.saveChangesSync();
返回更新尝试;
}

类条目是否仅在DB中的单个表中添加/更新,或者有多个表插入了一条记录,原因是其中一个子条目可能被锁定。在读取该实体时,必须找到该实体并使用Asnotracking(尽管这会有并发问题)。您可以使用ChangeTracker.Entries()查找被跟踪的条目。若要忽略其他字段的更新,需要在每个属性中将IsModified设置为false。类似这样的东西-this.Entry(Entry.Property)(x=>x.Property1.IsModified=false@拉维亚。我已经在使用AsNoTracking来读取实体,代码补充道。我看不出问题出在哪里我相信这通电话和DB之间的问题仍在跟踪中。您是否尝试了我建议的方法来查找仍在跟踪的条目?大多数情况下,它是子条目之一。我尝试的是一个简单的对象映射一对一的表,只是出于好奇,您是否应该将AsNoTracking添加到此行DALENTRY entry=wait _ctx.Set().SingleOrDefaultAsync(a=>a.ID==updateEntry.IdEntry);或者更新负责发布更改跟踪?