[英]EF Core SQLite Error 19: 'FOREIGN KEY constraint failed' despite configuring one to many
[英]SQLite EF Core - 'FOREIGN KEY constraint failed'
在我的 ASP.Net Core 项目中,我通过启动得到了这个异常,因为我在运行时初始化数据库:
失败:Microsoft.EntityFrameworkCore.Update[10000]
保存上下文类型“BlazorWeb.Server.Data.SQLiteTestDbContext”的更改时数据库发生异常。
Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。 有关详细信息,请参阅内部异常。Microsoft.Data.Sqlite.SqliteException (0x80004005):SQLite 错误 19:“外键约束失败”。
在 Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc,sqlite3 db)
....
我的模特:
public class ObjectModel : BaseEntity
{
[Key]
public int Id { get; set; }
public String Name { get; set; }
public String PreviewImage { get; set; }
public String TagName { get; set; }
// Foreign keys---
public int TypeId { get; set; }
public ObjectTypeModel TypeModel { get; set; }
//---
}
public class ObjectTypeModel : BaseEntity
{
[Key]
public int TypeId { get; set; }
public String Name { get; set; }
public String PreviewImage { get; set; }
public String TagName { get; set; }
public ICollection<ObjectModel> Objects { get; set; }
}
我在 DbContext 中的DbContext
OnModelCreating
方法:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ObjectModel>()
.HasOne<ObjectTypeModel>(d => d.TypeModel)
.WithMany(dm => dm.Objects)
.HasForeignKey(dkey => dkey.TypeId);
}
从自动生成的迁移 class:
name: "Objects",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedOn = table.Column<DateTime>(nullable: false),
ModifiedOn = table.Column<DateTime>(nullable: false),
Name = table.Column<string>(nullable: true),
PreviewImage = table.Column<string>(nullable: true),
TagName = table.Column<string>(nullable: true),
TypeId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Objects", x => x.Id);
table.ForeignKey(
name: "FK_Objects_ObjectTypes_TypeId",
column: x => x.TypeId,
principalTable: "ObjectTypes",
principalColumn: "TypeId",
onDelete: ReferentialAction.Cascade);
});
在我的初始化方法中,我只用一些数据填充它并将它们保存到上下文中。 但是数据库从来没有接收到这些记录,也出现了外键约束异常。
任何人都可以帮助我 - 我做错了什么吗?
编辑我发现异常发生在 SaveChangeAsync() 方法运行时之后。 我重写的SaveChangesAsyn()
方法:
public Task<int> SaveChangesAsync()
{
var entries = ChangeTracker
.Entries()
.Where(e => e.Entity is BaseEntity && (
e.State == EntityState.Added ||
e.State == EntityState.Modified));
foreach (var entityEntry in entries)
{
// overwrite `ModifiedOn` value with current date.
((BaseEntity)entityEntry.Entity).ModifiedO=
DateTime.Now;
// set `CreatedOn` to current date if its not already set.
if (entityEntry.State == EntityState.Added)
{
((BaseEntity)entityEntry.Entity).CreatedOn = DateTime.Now;
}
}
return base.SaveChangesAsync();
}
我在尝试删除一条与另一个 object 一对多关系的记录时遇到了同样的错误。
问题是在 DataContext 中未定义级联删除,您可以将以下内容添加到 DataContext 中:
modelbuilder.Entity<ObjectTypeModel>()
.HasMany(dm => dm.Objects)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
您的模型和迁移已更正。 主要原因是SaveChangesAsyn
时。
TypeId = table.Column<int>(nullable: false)
从这里我们可以看到,FK( TypeId
) 不可为空。 因此,您应该确认您的 FK( ObjectType
的TypeId
)不是 null 并且在添加新的 Object 时存在。
这是我添加 Object 的代码,型号与您相同。
public async Task<IActionResult> Create([Bind("Id,content,Deadline,IsComplete,UserId")] ToDoItem toDoItem)
{
if (ModelState.IsValid)
{
_context.Add(toDoItem);
await _context.SaveChangesAsync();
}
return View();
}
型号代码如下。
public class ToDoItem
{
public int Id { get; set; }
public string content { get; set; }
public DateTime Deadline { get; set; }
public bool IsComplete { get; set; }
public int UserId { get; set; }
public User user { get; set; }
}
public class User
{
public int Id { get; set; }
public string username { get; set; }
public string password { get; set; }
public ICollection<ToDoItem> ToDoItems { get; set; }
}
我有同样的问题,我必须使一个字段可以为空
这是一个示例,这为我解决了这个问题:
改变这个:
public int TypeId { get; set; }
对此:
public int? TypeId { get; set; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.