【发布时间】:2020-12-26 23:27:37
【问题描述】:
我有一个问题,我从现有的 MySQL 数据库中搭建了一个上下文和模型,该数据库包含一个父级到多个子级的关系。当我尝试创建新的父级和子级时,EF-core 返回错误外键关系已被违反。
我查看了 EF 是如何搭建它的,但看不到任何问题。出于某种原因,针对数据库执行的代码忽略了数据模型期望填充外键这一事实。 我错过了什么会导致这种关系被忽略?
以下是相关位:
- 表定义
- 自动脚手架上下文
- 执行保存的代码
- EF 生成的引发错误的 SQL 代码
这是两张表。注意 scan 上的外键,它是 item 的子项。
项目
CREATE TABLE `item` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(250) NOT NULL COLLATE 'utf8_general_ci',
`UPC` VARCHAR(20) NOT NULL COLLATE 'utf8_general_ci',
`friendly_name` VARCHAR(250) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`date_created` DATETIME NOT NULL DEFAULT current_timestamp(),
`date_deleted` DATETIME NULL DEFAULT NULL,
`is_homemade` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=287
;
扫描
CREATE TABLE `scan` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`item_id` INT(11) NOT NULL DEFAULT -1,
`expiration_date` DATETIME NULL DEFAULT NULL,
`use_date` DATETIME NULL DEFAULT NULL,
`create_date` DATETIME NOT NULL DEFAULT current_timestamp(),
`delete_date` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `fk_item_instance_item` (`item_id`) USING BTREE,
CONSTRAINT `fk_item_instance_item` FOREIGN KEY (`item_id`) REFERENCES `inventory`.`item` (`id`) ON UPDATE CASCADE ON DELETE RESTRICT
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=537
;
用于映射外键的上下文中的脚手架代码。这出现在模型构建器的扫描端。
entity.HasOne(d => d.Item)
.WithMany(p => p.Scan)
.HasForeignKey(d => d.ItemId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_item_instance_item");
当我执行以下代码来创建具有关联的新扫描的新项目时,我从数据库中收到一个错误。
var newItem = new Item()
{
Name = scan.Name,
Upc = scan.UPC,
DateCreated = DateTime.Now,
};
var newScan = new Scan()
{
Item = newItem,
CreateDate = DateTime.Now,
ExpirationDate = scan.ExpirationDate,
};
newItem.Scan = new List<Scan>() { newScan };
if (ModelState.IsValid)
{
_context.Item.Add(newItem);
_context.Entry(newScan).State = EntityState.Added;
await _context.SaveChangesAsync();
...
数据库抛出一个错误,抱怨外键是如何被违反的。查看创建的 SQL,我可以肯定地看到它没有将项目映射到扫描。
INSERT INTO `item` (`date_created`, `date_deleted`, `friendly_name`, `is_homemade`, `name`, `UPC`)
VALUES (timestamp('2020-09-08 10:09:38.033399'), NULL, NULL, false, 'test item', 'testing');
SELECT `id`
FROM `item`
WHERE ROW_COUNT() = 1 AND `id` = LAST_INSERT_ID()
INSERT INTO `scan` (`create_date`, `delete_date`, `expiration_date`, `use_date`)
VALUES (timestamp('2020-09-08 10:09:38.037147'), NULL, NULL, NULL);
SELECT `id`, `item_id`
FROM `scan`
WHERE ROW_COUNT() = 1 AND `id` = LAST_INSERT_ID()
【问题讨论】:
标签: c# mysql asp.net-mvc entity-framework-core entity-framework-core-3.1