rur*_*gle 5 c# npgsql entity-framework-core asp.net-core
我目前正在尝试使用 ASP.NET Core 6 MVC 和 Entity Framework Core 6 和 npgsql 启动一个新项目。
\n当我尝试添加一个具有外国身份的实体时ModelState.IsValid不断返回 false - 因为模型不会扩展外国实体。
基本上我遵循了官方文档:
\n所以我的课程看起来像:
\nnamespace PV.Models\n{\n public class Fakultaet\n {\n [Key]\n public int FakultaetID { get; set; }\n [Required]\n public string FakuName { get; set; }\n }\n\n public class Studiengang\n {\n [Key]\n public int StudiengangID { get; set; }\n [Required]\n public string StudiengangName { get; set;}\n [Required,ForeignKey("Fakultaet")]\n public int FakultaetID { get; set; }\n \n public Fakultaet Fakultaet { get; set; }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n部分视图:
\n@model PV.Models.Studiengang\n<tr>\n <td>\n <div asp-validation-summary="ModelOnly" class="text-danger"></div>\n <input asp-for="StudiengangName" class="form-control" />\n <span asp-validation-for="StudiengangName" class="text-danger"></span>\n </td>\n <td>\n <select asp-for="FakultaetID" class="form-control" asp-items="ViewBag.FakultaetId">\n <option disabled="disabled" selected="selected" value="0">Bitte w\xc3\xa4hlen...</option>\n </select>\n <span asp-validation-for="FakultaetID" class="text-danger"></span>\n </td>\n <td>\n <input type="submit" value="Speichern" class="btn btn-outline-success btn-sm" id="btn-addinline-submit" />\n <input type="reset" onClick="location.reload()" class="btn btn-outline-danger btn-sm" id="btn-addinline-abort" value="Abbrechen" />\n </td>\n</tr>\nRun Code Online (Sandbox Code Playgroud)\n控制器:
\nnamespace PV.Controllers\n{\n public class StudiengangController : Controller\n {\n private readonly PraktikumsKontext _context;\n\n public StudiengangController(PraktikumsKontext ctx)\n {\n _context = ctx;\n }\n \n // --- snip ---\n\n // GET: Student/Add\n public IActionResult AddStudiengangInline()\n {\n ViewBag.FakultaetId = new SelectList(_context.Fakultaeten.AsNoTracking(), "FakultaetID", "FakuName");\n return PartialView();\n }\n\n // POST: Student/Add\n [HttpPost]\n [ValidateAntiForgeryToken]\n public async Task<IActionResult> AddStudiengangInline([Bind("StudiengangName, FakultaetID")] Studiengang studiengang )\n {\n if (ModelState.IsValid)\n {\n _context.Add(studiengang);\n await _context.SaveChangesAsync();\n return RedirectToAction("Index");\n }\n\n ViewData["FakultaetId"] = new SelectList(_context.Fakultaeten, "FakultaetID", "FakuName", studiengang.FakultaetID);\n\n return PartialView(studiengang);\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n当我现在填写表格并发布StudiengangName=Test1234;FakultaetID=1(使用现有Fakultaet的ID = 1时,我的模型确实如下所示:
StudiengangID = 0\nStudiengangName = "Test1234"\nFakultaet = null\nFakultaetID = 1\nRun Code Online (Sandbox Code Playgroud)\n因此ModelState.IsValid返回false原样Fakultaetnull。
在这里,我假设 EF Core 6 发挥了它的魔力并解析了我引用的实体。
\n如果我在检查模型是否有效之前添加以下代码片段,那么一切似乎都有效:
\nStudiengangID = 0\nStudiengangName = "Test1234"\nFakultaet = null\nFakultaetID = 1\nRun Code Online (Sandbox Code Playgroud)\n但这似乎是一个肮脏的解决方法,因为在具有几乎相同设置的 .NET Core 3.1 中没有必要。
\n有人知道我缺少什么吗?
\n正如这份文件所说:
从 .NET 6 开始,新项目
<Nullable>enable</Nullable>在项目文件中包含该元素。一旦启用该功能,现有的引用变量声明将变为 不可为空的引用类型。
在 .NET 6 中,必须要求不可为 null 的属性,否则 ModelState 将无效。
为了达到您的要求,您可以<Nullable>enable</Nullable>从项目文件中删除。
第二种方法,您可以像下面这样初始化模型:
public class Studiengang
{
[Key]
public int StudiengangID { get; set; }
[Required]
public string StudiengangName { get; set;}
[Required,ForeignKey("Fakultaet")]
public int FakultaetID { get; set; }
public Fakultaet Fakultaet { get; set; } = new Fakultaet();
}
Run Code Online (Sandbox Code Playgroud)
第三种方法,您可以添加?允许可为空:
public class Studiengang
{
[Key]
public int StudiengangID { get; set; }
[Required]
public string StudiengangName { get; set;}
[Required,ForeignKey("Fakultaet")]
public int FakultaetID { get; set; }
public Fakultaet? Fakultaet { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
最后一种方法就像您在模型验证中删除密钥所做的那样。