为了账号安全,请及时绑定邮箱和手机立即绑定

创建方法尝试从表单中插入 FK 作为 ID

创建方法尝试从表单中插入 FK 作为 ID

C#
qq_花开花谢_0 2023-08-13 16:08:25
我正在尝试将新数据插入到我的一个表中,但我收到了身份插入错误,即使我从未真正设置过 ID。我可以用创可贴修复此问题,但我想了解为什么会发生这种情况以及最佳实践是什么如果我在添加到 DbContext 之前将 Id 设置为 0,它可以正常工作,但我根本不明白我的 Id 是在哪里设置的。这是我的模型:public class Question : BaseModel{    public QuestionGroup QuestionGroup { get; set; }    public int QuestionGroupId { get; set; }    [Display(Name ="Question Text")]    public string QuestionText { get; set; }    public string Type { get; set; }}public class BaseModel{    public int Id { get; set; }    [Display(AutoGenerateField = false), JsonIgnore]    public DateTime CreatedAt { get; set; }    [Display(AutoGenerateField = false), JsonIgnore]    public DateTime UpdatedAt { get; set; }}这是我的相关控制器代码:(如果我取消注释将 Id 设置为 0,则可以正常工作)[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Create(Question question){    //question.Id = 0;    if (ModelState.IsValid)    {        _context.Add(question);        await _context.SaveChangesAsync();        return RedirectToAction("Details", "QuestionGroups", new { id =         question.QuestionGroupId });    }    await PopulateId(question.QuestionGroupId);    return View(question);}这是我的表格:<div class="col-md-4">    <form asp-action="Create" enctype="multipart/form-data">        <div asp-validation-summary="ModelOnly" class="text-danger"></div>        <input asp-for="QuestionGroupId" type="hidden"         value="@ViewBag.QuestionGroupId"/>        <div class="form-group">            <label asp-for="QuestionText" class="control-label"></label>            <input asp-for="QuestionText" class="form-control" />            <span asp-validation-for="QuestionText" class="text-danger></span>        </div>这是有道理的,因为当我调试时,我看到的是:
查看完整描述

3 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

很奇怪。我所能建议的只是尝试使 Id 属性不是自动的,以通过查看调用堆栈来找出它的设置位置。


private int _id;

public int Id 

   get { return _id; }

   set { _id = value; } 

}

并使用“set”设置断点


查看完整回答
反对 回复 2023-08-13
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

ASP.NET Core我尝试通过使用以下代码创建项目来重新生成您的错误:


public class BaseModel

{

    public int Id { set; get; }

    public DateTime CreatedAt { get; set; }

    public DateTime UpdatedAt { get; set; }

}


public class Question : BaseModel

{

    public string QuestionText { get; set; }

    public string Type { get; set; }

}


//Startup.cs

        services.AddDbContext<ApplicationDbContext>(options => 

        {

            options.UseSqlite(

                Configuration.GetConnectionString("DefaultConnection")

            );

        });



//Home Controller

    public IActionResult Test()

    {

        _applicationDbContext.Questions.Add(new Question

        {

            Id = 0, //Changing this value affects the behaviour of the application

            QuestionText = "Question text"

        });


        _applicationDbContext.SaveChanges();

        return View(_applicationDbContext.Questions.ToList());

    }

但是,我无法重新生成您的相同错误。当Id(Test()方法中) 未设置或设置为等于 0 时,它可以工作。如果我设置为大于 0 的数字,例如 100,它第一次可以工作,但在下次运行中会失败,并显示以下错误消息:


SQLite 错误 19:“UNIQUE 约束失败:Questions.Id”


如您所见,我在这里使用 SQLite。生成的迁移如下:


        protected override void Up(MigrationBuilder migrationBuilder)

    {

        migrationBuilder.CreateTable(

            name: "Questions",

            columns: table => new

            {

                Id = table.Column<int>(nullable: false)

                    .Annotation("Sqlite:Autoincrement", true),

                CreatedAt = table.Column<DateTime>(nullable: false),

                UpdatedAt = table.Column<DateTime>(nullable: false),

                QuestionText = table.Column<string>(nullable: true),

                Type = table.Column<string>(nullable: true)

            },

            constraints: table =>

            {

                table.PrimaryKey("PK_Questions", x => x.Id);

            });

    }

这里,Idfield被创建为身份字段。


我可以得出的结论是,您的Id字段是作为identity数据库自动设置的字段创建的。所以你不应该为它设置一个特定的值。也许在您处理的某个地方设置了非零值。正如 @feihoa 所说,此时的断点和调试会话可能会有所帮助。


startup.cs如果问题仍然存在,您的配置代码、迁移代码以及有关您正在使用的数据库类型的信息可能会有所帮助。


查看完整回答
反对 回复 2023-08-13
?
繁花如伊

TA贡献2012条经验 获得超12个赞

事实证明,我的问题实际上出在我的 create 方法中。这是损坏的代码:



// GET: Questions/Create

        public IActionResult Create(int? id)

        {

            if (id == null) {

                return NotFound();

            }

            PopulateId(id);

            return View();

        }

修复:



// GET: Questions/Create

        public IActionResult Create(int? questionGroupId)

        {

            if (questionGroupId== null) {

                return NotFound();

            }

            PopulateId(questionGroupId);

            return View();

        }

由于默认启动有这个模板:



app.UseMvc(routes =>

            {

                routes.MapRoute(

                    name: "default",

                    template: "{controller=Home}/{action=Index}/{id?}");

            });

综上所述:


这是一个非常简单的错误,因为我使用了糟糕的命名。默认的 create get 方法没有 ID,但由于我需要对页面上的父对象执行一些操作,因此我必须将其传递到我的视图,并且 .Net 将我的 QuestionId(子级)设置为 QuestionGroupId (父)。


我希望这对遇到此问题的其他人有所帮助。


感谢评论者的帮助


查看完整回答
反对 回复 2023-08-13
  • 3 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信