C# 创建尝试从窗体中插入FK作为ID的方法
我试图将新数据插入到我的一个表中,但却出现了标识插入错误,尽管我从未真正设置过标识 我可以用绷带解决这个问题,但我想知道为什么会发生这种情况,最好的做法是什么 如果我在添加到DbContext之前将Id设置为0,它会正常工作,但我根本不知道我的Id设置在哪里 这是我的模型:C# 创建尝试从窗体中插入FK作为ID的方法,c#,.net-core,C#,.net Core,我试图将新数据插入到我的一个表中,但却出现了标识插入错误,尽管我从未真正设置过标识 我可以用绷带解决这个问题,但我想知道为什么会发生这种情况,最好的做法是什么 如果我在添加到DbContext之前将Id设置为0,它会正常工作,但我根本不知道我的Id设置在哪里 这是我的模型: 公共类问题:BaseModel { 公共问题组问题组{get;set;} public int QuestionGroupId{get;set;} [显示(Name=“问题文本”)] 公共字符串QuestionText{ge
公共类问题:BaseModel
{
公共问题组问题组{get;set;}
public int QuestionGroupId{get;set;}
[显示(Name=“问题文本”)]
公共字符串QuestionText{get;set;}
公共字符串类型{get;set;}
}
公共类基模型
{
公共int Id{get;set;}
[显示(AutoGenerateField=false),JsonIgnore]
public DateTime CreatedAt{get;set;}
[显示(AutoGenerateField=false),JsonIgnore]
public DateTime UpdatedAt{get;set;}
}
以下是我的相关控制器代码:(如果我取消注释将Id设置为0,它就可以正常工作)
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务创建(问题)
{
//问题Id=0;
if(ModelState.IsValid)
{
_增加(问题);
wait_context.SaveChangesAsync();
return RedirectToAction(“详细信息”,“问题组”,新{id=
question.QuestionGroupId});
}
等待PopulateId(问题.问题组ID);
返回视图(问题);
}
这是我的表格:
很奇怪。我所能建议的只是试着让Id属性不自动,从调用堆栈中找出它的设置位置
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
并在“set”行上设置断点我试图通过使用以下代码创建一个ASP.NET Core
项目来重新生成您的erro:
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
字段被创建为标识字段
我可以得出的结论是,您的Id
字段被创建为一个identity
字段,该字段由数据库自动设置。因此,不应为其设置特定值。可能在处理过程中的某个地方设置了非零值。正如@feihoa所说,在该点上设置断点和调试会话可能会有所帮助
如果问题仍然存在,您在startup.cs
中的配置代码、迁移代码和有关您正在使用的数据库类型的信息可能会有所帮助。事实证明,我的问题实际上是在create的get方法中。以下是被破坏的代码:
//获取:问题/创建
公共IActionResult创建(int?id)
{
if(id==null){
返回NotFound();
}
大众id(id);
返回视图();
}
修复方法:
//获取:问题/创建
公共IActionResult创建(int?questionGroupId)
{
if(questionGroupId==null){
返回NotFound();
}
PopulateId(问题组ID);
返回视图();
}
由于默认启动具有此模板:
app.UseMvc(路由=>
{
routes.MapRoute(
名称:“默认”,
模板:“{controller=Home}/{action=Index}/{id?}”);
});
总之:
这是一个非常简单的错误,因为我使用了糟糕的命名。默认的create get方法没有ID,但由于我需要对页面上的父对象执行一些操作,所以我必须将其传递给我的视图,并且.Net正在将我的questionId(子对象)设置为questionGroupId(父对象)
我希望这能帮助任何遇到这个问题的人
感谢评论员的帮助也许问题类意外地包含了Id=QuestionGroupId之类的内容?这是什么:_context.Add(问题)@feihoa在我的问题类中除了名称空间等内容外没有其他内容。您的Id在_context.SaveChangesAsync()之前或之后不是0?我猜是之前,那么您是否使用javascript提交表单?@feihoa调试是从post方法的第一行开始的,因此在_context.SaveChangesAsync()之前不是0。除了我发布的表单html代码之外,没有其他任何东西会影响表单。我对这件事真是摸不着头脑
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());
}
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);
});
}