微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用外键的 ASP.NET Core Web API

如何解决使用外键的 ASP.NET Core Web API

我正在为用户控制器开发 Web Api 操作,但我不明白为什么在 POST 方法中出现错误

违反了 PRIMARY KEY 约束的“PK_Section”。无法将重复键插入 dbo.Section 对象。重复键值:(3fa85f64-5717-4562-b3fc-2c963f66afa4)。

我的 IdentityUser 模型:


        public string MiddleName { get; set; }

        [required]
        public string Surname { get; set; }

        public DateTime BirthDate { get; set; }

        public string Address { get; set; }

        [required]
        public string UserType { get; set; }
        public bool ParentsAgreement { get; set; }

        public Section BelongSection { get; set; }
    

截面模型:

        [required]
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string CoachName { get; set; }
        public string SportComplexTitle { get; set; }
        [IgnoreDataMember]
        public ICollection<User> UsersList { get; set; }

数据库上下文:

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            //section
            modelBuilder.Entity<User>()
                .HasOne(s => s.BelongSection)
                .WithMany(a => a.UsersList);

            modelBuilder.Entity<Section>()
                .HasMany(s => s.UsersList)
                .WithOne(a => a.BelongSection);
        }

还有我的 POST 方法

        [HttpPost]
        public async Task<ActionResult<User>> Add(User user)
        {
            try
            {
                if (user == null)
                {
                    return BadRequest();
                }

                myDbContext.Users.Add(user);
                await myDbContext.SaveChangesAsync();

                var result = await myDbContext.Users.Include(o => o.BelongSection).FirstOrDefaultAsync(o 
                     => o.Id == user.Id);
                return result;

            }
            catch (Exception)
            {
                throw;
            }
        }

所以,我收到错误,我不能在创建用户时使用现有部分的 ID。 我的 Post 方法主体是:

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6","userName": "string","normalizedUserName": "string","email": "string","normalizedEmail": "string","emailConfirmed": true,"passwordHash": "string","securityStamp": "string","concurrencyStamp": "string","phoneNumber": "string","phoneNumberConfirmed": true,"twoFactorEnabled": true,"lockoutEnd": "2021-04-15T08:31:12.271Z","lockoutEnabled": true,"accessFailedCount": 0,"name": "string","middleName": "string","surname": "string","birthDate": "2021-04-15T08:31:12.271Z","address": "string","userType": "string","parentsAgreement": true,"belongSection": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa4"
  }
}

解决方法

您可以使用两种方法将现有子项添加到父项,如下所示:

_context.Section.Attach(user.BelongSection);

或者:

_context.Entry(user.BelongSection).State = EntityState.Unchanged;

务必添加 AsNoTracking() 以显示结果。

这是整个工作演示:

[HttpPost]
public async Task<ActionResult<User>> Add(User user)
{
    try
    {
        if (user == null)
        {
            return BadRequest();
        }
        //_context.Section.Attach(user.BelongSection);
        _context.Entry(user.BelongSection).State = EntityState.Unchanged;

        _context.Users.Add(user);
        await _context.SaveChangesAsync();


        var result = await _context.Users.Include(o => o.BelongSection)
                                   .AsNoTracking()
                                   .FirstOrDefaultAsync(o=> o.Id == user.Id);
        return result;

    }
    catch (Exception)
    {
        throw;
    }
}

注意

不确定你的asp.net core版本是什么,记得加ReferenceLoopHandling.Ignore

在 asp.net core 3.x 中,System.Text.Json 仅支持按值序列化,并且会引发循环引用异常。所以你需要像下面这样添加 Newtonsoft 支持:

services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

}); 

在 .Net 5.0 中,您还可以添加 Newtonsoft 支持。此外,System.Text.Json 允许将 ReferenceHandler 设置为 Preserve

https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-preserve-references?pivots=dotnet-5-0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。