Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework core 无法使用实体框架核心2.1更新子实体_Entity Framework Core_Automapper 5 - Fatal编程技术网

Entity framework core 无法使用实体框架核心2.1更新子实体

Entity framework core 无法使用实体框架核心2.1更新子实体,entity-framework-core,automapper-5,Entity Framework Core,Automapper 5,我是EF的新手,正在努力做一个基本的更新。我读过很多关于类似问题的帖子。据我所知,这在EF Core 2.1中目前并不容易做到,需要复杂的解决方法。 这实际上是可能的,还是应该直接单独更新子实体 注意:如果我只是更新exampleA,而不包括子实体,它可以正常工作 我得到以下错误: 处理请求时发生未处理的异常。 InvalidOperationException:无法跟踪实体类型“ExampleB”的实例,因为已在跟踪另一个具有{Id'}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键

我是EF的新手,正在努力做一个基本的更新。我读过很多关于类似问题的帖子。据我所知,这在EF Core 2.1中目前并不容易做到,需要复杂的解决方法。 这实际上是可能的,还是应该直接单独更新子实体

注意:如果我只是更新exampleA,而不包括子实体,它可以正常工作

我得到以下错误:

处理请求时发生未处理的异常。 InvalidOperationException:无法跟踪实体类型“ExampleB”的实例,因为已在跟踪另一个具有{Id'}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例。考虑使用“dBraveTopStudioBuff.EnabelSythViDeAtGracg”来查看冲突的键值。 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.ThroWideTityConflict(InternalEntityEntry条目)

堆栈查询Cookies头 InvalidOperationException:无法跟踪实体类型“ExampleB”的实例,因为已在跟踪另一个具有{Id'}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例。考虑使用“dBraveTopStudioBuffel.EnabelSythViDeAtCug”来查看冲突的键值。

我已经为这个问题创建了一个基本示例。 第一个stackoverflow帖子也让我知道,如果需要更多的信息

任何帮助都将不胜感激

WebAPI控制器:

[HttpPut]
    public async Task<ActionResult> UpdateExample(ExampleADto exampleADto)
    {
        var exampleAFromDB = await _context.ExampleA.Include(x => x.ExampleBs).Where(x => x.Id == exampleADto.Id).SingleOrDefaultAsync();

        if (exampleAFromDB == null)
            return NotFound();

        _mapper.Map(exampleADto, exampleAFromDB);

        if (await _context.SaveChangesAsync() > 0)
            return Ok(exampleAFromDB);

        throw new Exception("Failed to update ExampleA"); 
    }
例如:

{
    "id": 1,
    "description": "Example A1 Updated",
    "exampleBDtos": [
        {
            "id": 1,
            "description": "B1 Updated",
            "someNumber": 1
        },
        {
            "id": 2,
            "description": "B2",
            "someNumber": 2
        },
        {
            "id": 3,
            "description": "B3",
            "someNumber": 3
        }
    ]
}
自动映射后的示例a:

{
"id": 1,
"description": "Example A1 Updated",
"exampleBDtos": [
    {
        "id": 1,
        "description": "B1 Updated",
        "someNumber": 1
    },
    {
        "id": 2,
        "description": "B2",
        "someNumber": 2
    },
    {
        "id": 3,
        "description": "B3",
        "someNumber": 3
    }
]
}

更新失败(无更改)后数据库中的示例A:

自动映射配置文件:

public AutoMapperProfiles()
    {
        CreateMap<ExampleA, ExampleADto>()
            .ForMember(x => x.ExampleBDtos, opt => opt.MapFrom(x => x.ExampleBs));
        CreateMap<ExampleB, ExampleBDto>();

        CreateMap<ExampleADto, ExampleA>()
            .ForMember(x => x.ExampleBs, opt => opt.MapFrom(x => x.ExampleBDtos));
        CreateMap<ExampleBDto, ExampleB>();
    }
public automapper profiles()
{
CreateMap()
.ForMember(x=>x.examplebttos,opt=>opt.MapFrom(x=>x.ExampleBs));
CreateMap();
CreateMap()
.ForMember(x=>x.ExampleBs,opt=>opt.MapFrom(x=>x.ExampleBDtos));
CreateMap();
}
更新1: 自动映射后添加的对象

更新2: 似乎Automapper不会在不删除和重新创建与EF冲突的项目的情况下映射集合


AutoMapper.Collection目前不适用于EF Core,因此我自己创建了一个函数来手动映射和更新集合。

检查AutoMapper.Collection.AutoMapping似乎可以正常工作。在AutoMapper映射对象之后,我在帖子中添加了该对象。请将其添加到您的查询中,AsNoTracking(),这可能会对您有所帮助。顺便说一句,避免使用VAR,并以强类型的方式尝试它。很快,您应该自己处理它。自动映射似乎只起作用,因为它将集合项替换为新实例,这反过来会导致EF核心异常。正如Lucian指出的,AutoMapper.Collection可以帮助添加/更新子实体。但不能使用delete。你也可以试试,但我没有试过,也不能分享我的观点。非常感谢@IvanStoev的解释。我已经通过手动更新集合中的实体确认了automapper的问题,这是可行的。我将看看如何使用AutoMapper.Collection。关于是否有计划在EF Core/Automapper或是Automapper.Collections中解决这个问题,你有什么想法吗?
{
    "id": 1,
    "description": "Example A1",
    "exampleBDtos": [
        {
            "id": 1,
            "description": "B1",
            "someNumber": 1
        },
        {
            "id": 2,
            "description": "B2",
            "someNumber": 2
        },
        {
            "id": 3,
            "description": "B3",
            "someNumber": 3
        }
    ]
}
public AutoMapperProfiles()
    {
        CreateMap<ExampleA, ExampleADto>()
            .ForMember(x => x.ExampleBDtos, opt => opt.MapFrom(x => x.ExampleBs));
        CreateMap<ExampleB, ExampleBDto>();

        CreateMap<ExampleADto, ExampleA>()
            .ForMember(x => x.ExampleBs, opt => opt.MapFrom(x => x.ExampleBDtos));
        CreateMap<ExampleBDto, ExampleB>();
    }