![](/img/trans.png)
[英]Entity Framework + AutoMapper ( Entity to DTO and DTO to Entity )
[英]Automapper DTO to Entity Framework Core model
I'm building my first .NET Core 3.1 API, I have problem with properly map DTO to model, I'm sending JSON with userId of existing user:
{
"userId": 0,
"storageName": "string"
}
它拋出一個錯誤,看起來它正在嘗試從數據庫中為現有用戶創建新的而不是 map
后端_API_DEV | 失敗:Microsoft.EntityFrameworkCore.Database.Command[20102] Backend_API_DEV |
執行 DbCommand (43ms) 失敗 [Parameters=[@p0='?' (DbType = Int32), @p1='?' (大小 = 4000),@p2='?' (大小 = 4000),@p3='?' (大小 = 4000)],CommandType='Text',CommandTimeout='30']
后端_API_DEV | 設置無計數;
后端_API_DEV | 插入 [Users]([UserId]、[UserEmail]、[UserName]、[UserPassword])
后端_API_DEV | 值(@p0、@p1、@p2、@p3);
后端_API_DEV | 失敗:Microsoft.EntityFrameworkCore.Update[10000]
后端_API_DEV | 保存上下文類型“Backend.Data.BackendContext”的更改時,數據庫中發生異常。
我使用的其他 DTO/模型沒有外鍵,它們 map 正確,所以我可以在數據庫中創建和更新對象。 我認為我的問題是 map 配置,但我不知道如何正確地做到這一點。
namespace Backend.Profiles
{
public class StorageProfile : Profile
{
public StorageProfile()
{
CreateMap<StorageCreateDto, Storage>()
.ForPath(dest => dest.IdUser.UserId, opt => opt.MapFrom(src => src.UserId));
}
}
}
Model:
namespace Backend.Models
{
public class Storage
{
[Key]
public int StorageId { get; set; }
[ForeignKey("UserId")]
public virtual User IdUser { get; set; }
[Required]
public string StorageName { get; set; }
}
}
Controller:
namespace Backend.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class StorageController : ControllerBase
{
private readonly IBackendRepo _repository;
private readonly IMapper _mapper;
public StorageController(IBackendRepo repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
[HttpPost]
public ActionResult<StorageReadDto> CreateStorage(StorageCreateDto storageCreateDto)
{
var model = _mapper.Map<Storage>(storageCreateDto);
_repository.CreateStorage(model);
_repository.SaveChanges();
var readDto = _mapper.Map<StorageReadDto>(model);
return CreatedAtRoute(nameof(GetStorageById), new { Id = readDto.StorageId }, readDto);
}
}
}
將更改保存到數據庫的存儲庫:
public bool SaveChanges()
{
return (_context.SaveChanges() >= 0);
}
public void CreateStorage(Storage storage)
{
if (storage == null)
{
throw new ArgumentNullException(nameof(storage));
}
_context.Storages.Add(storage);
}
如果storage.User
是非空引用,則將storage
添加到上下文:
_context.Storages.Add(storage);
還添加了引用的User
。 這就是DbSet<T>.Add
的工作原理——它添加了整個 object 圖。
有兩種選擇:
重新設計Storage
以添加外鍵屬性UserId
。 將 DTO 映射到存儲時,初始化外鍵屬性而不是引用屬性。 也就是初始化用戶id而不是user。 (另外,最好重命名IdUser
屬性,這樣的名稱會混淆,因為這不是標識符,而是引用)。
添加storage
后,將引用用戶的 state 顯式設置為Unchanged
:
_context.Entry(storage.IdUser).State = EntityState.Unchanged;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.