c# - 在 ASP.Net Core 3.0 中使用表单添加到模型的 IList
问题描述
在尝试学习 ASP.Net Core 的过程中,我决定做一个论坛是一个很好的学习项目。
本着这种精神,我创建了这些模型:
public class Topic
{
public int Id {get; set;}
public int PostCount {get; set;}
public string Title {get; set;}
public string OriginalPoster {get; set;}
public IList<Post> Posts{get; set;}
}
public class Post
{
public int Id {get; set;}
public DateTime TimeStamp {get; set;}
public string Poster {get; set;}
public string Body {get; set;}
}
现在,很明显,当一个人创建一个论坛主题时,一个人也应该创建他们的第一个帖子,以免你留下一个无头的标题。
因此,我创建这个表单的印象是它会让我获得第一个帖子(一旦它起作用,我可以很容易地处理 Post 模型的其他部分):
<form asp-action="Create" asp-controller="Topic" method = "post">
<div class="form-group"><label asp-for="Title"></label>
<input asp-for="Title"></div>
@Html.TextAreaFor(e => e.Posts[0].Body, 10, 55, null) <br />
<button type="submit" class="btn btn-default">Submit</button>
Create
但是,当我在我的方法中放置一个断点时,TopicController
它向我显示这不起作用(我怀疑这是由于我从未创建过新的 Post 实例)。我得到:
Microsoft.EntityFrameworkCore.DbUpdateConcurrency 异常
说预计会影响 1 行,但是我的数据库上下文的SaveChanges
方法会影响 0 行。有什么方法可以创建一个新的 Post 实例并将其添加到我IList<Post>
的表单中?
我的控制器的Create
功能如下:
[HttpPost]
public IActionResult Create(Topic tops)
{
if (tops is null)
{
throw new System.ArgumentNullException(nameof(tops));
}
tops.Posts[0].TimeStamp = DateTime.Now;
db.Topics.Add(tops);
db.SaveChanges(); // <-- Error happens here
return View("Topics", db.Topics.ToList());
}
任何和所有的帮助将不胜感激。
Topics 的 MySQL 表如下:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| Id | varchar(20) | YES | | NULL | |
| PostCount | int(11) | YES | | NULL | |
| Title | varchar(20) | YES | | NULL | |
| OriginalPoster | varchar(20) | YES | | NULL | |
+----------------+-------------+------+-----+---------+-------+
对于邮政:
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| Id | int(11) | NO | PRI | NULL | auto_increment |
| TimeStamp | datetime(6) | NO | | NULL | |
| Poster | longtext | YES | | NULL | |
| Body | longtext | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
解决方案
原因
- 我认为您实际上并没有写入数据库,您的主题模型中的 IList < post > 字段实际上并不存在于数据库中,因此您无法插入它。
解决方案
- 数据库设计存在问题。这是一个典型的一对多数据集问题。您需要将这两个表与外键相关联,以便您可以根据键值更新您的 post 表。
- 您的数据库表应修改为如下所示
public class Topic
{
[ScaffoldColumn(false)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TopicId { get; set; }
public int PostCount { get; set; }
public string Title { get; set; }
public string OriginalPoster { get; set; }
}
public class Post
{
[ScaffoldColumn(false)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PostId { get; set; }
public int TopicId { get; set; }
[ForeignKey("TopicId")]
public DateTime TimeStamp { get; set; }
public string Poster { get; set; }
public string Body { get; set; }
}
- 我复制了您的代码并将其放在 GitHub 上。您可以单击此链接查看我如何实现插入操作。这是插入部分的代码
[HttpPost]
public async Task<IActionResult> CreateTopic(TopicViewModel model)
{
var topic = new Topic
{
Title = model.Title,
OriginalPoster = model.OriginalPoster,
PostCount = model.PostCount
};
await _context.AddAsync(topic);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
[HttpPost]
public async Task<IActionResult> CreatePost(PostViewModel model)
{
var post = new Post
{
TopicId = model.TopicId,
TimeStamp = model.TimeStamp,
Poster = model.Poster,
Body = model.Body
};
await _context.AddAsync(post);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
- 通过上面的描述和代码应该可以解决你当前的问题。
其他提示
推荐阅读
- angular - Should i disable change detection during angular app init phase?
- apache-kafka - Create schema from JSON to write Parquet to HDFS with Kafka Sink
- c# - 良好实践 - C# 中的私有事件与私有方法
- javascript - Angular 2 - 使用 AOT 构建:Javascript 堆内存不足
- swift - 压缩我的音频文件后,为什么我不能播放文件?
- c# - 使用 .net 核心声纳扫描仪将声纳结果发布到 tfs 构建
- node.js - find all documents of all collections in db of mongoose using express
- ios - 斯威夫特:如何使所有正在运行的计时器无效?
- r - dplyr 按变量等级折叠但忽略 NA
- ios - MTLDevice 类需要 id<>