SqliteException: SQLite Error 19: ‘FOREIGN KEY constraint failed‘.

需求:

发表动态可以没有标签,允许导航属性为空。

现象:

使用EFCore库框架,添加数据时出现。

截图:

数据表

cs 复制代码
    public class Moment
    {
        public ulong MomentID {  get; set; }
        public string Content { get; set; } = string.Empty;

        public ulong LableID {  get; set; }
 
        public Lable Lable { get; set; }    
    }
cs 复制代码
 public class Lable
 {
     public ulong LableID { get; set; }
     public string Name { get; set; } = string.Empty;

     public List<Moment> Moments { get; set; }
 }

DbContext

cs 复制代码
  public class DataBaseContext : DbContext
  {
      public DbSet<Moment> Moments { get; set; }
      public DbSet<Lable> Lables { get; set; }
 
      public string DbPath { get; }
     
      public DataBaseContext()
      {
          var folder = Environment.CurrentDirectory;

          DbPath = Path.Join(folder, "DataBase.db");
          Database.EnsureCreatedAsync();
          Log.Info("启动EFCore: " + DbPath);
      }

   
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {             
          modelBuilder.Entity<Moment>().HasKey(x => x.MomentID);
          modelBuilder.Entity<Lable>().HasKey(x => x.LableID);
          modelBuilder.Entity<Moment>().HasOne(x => x.Lable).WithMany(x => x.Moments).HasForeignKey(x => x.LableID);
      }

      protected override void OnConfiguring(DbContextOptionsBuilder options)
      {
          options.UseSqlite($"Data Source={DbPath}");
          options.LogTo(Log.Debug);
      }
  }

Program插入数据代码

cs 复制代码
namespace EFCore
{
    using System;
    using System.ComponentModel;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Reflection.Metadata;
    using System.Text;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Migrations;
    using Microsoft.EntityFrameworkCore.Migrations.Operations;

    internal class Program
    {
        static void Main(string[] args)
        {
            var folder = Environment.CurrentDirectory;
            var db = new DataBaseContext();
 
            Lable l = db.Lables.Where(x => x.Name == "意难平").ToList().FirstOrDefault(); ;

            if (l == null)
            {
                l = new Lable();
                l.LableID = 1;
                l.Name = "意难平";
                db.Lables.Add(l);
                db.SaveChanges();
                Console.WriteLine("添加标签完毕");
            }
            else
            {
                Console.WriteLine("标签存在");
            }
 
            Moment query = db.Moments.Where(x => x.Content == "爱意随风起,风止意难平。").ToList().FirstOrDefault();

            if (query == null)
            {
                query = new Moment();
                query.MomentID = (ulong)DateTime.Now.ToFileTime();
                query.Content = "爱意随风起,风止意难平。";
 
                db.Moments.Add(query);
                db.SaveChanges();
                Console.WriteLine("添加动态成功");
            }
            else
            {
                Console.WriteLine("动态存在");
            }
            Console.ReadKey();
        }
    }
}

以上代码运行则会报错,

SqliteException: SQLite Error 19: 'FOREIGN KEY constraint failed'.

表预览

改进代码V1

增加IsRequired(false)

则会报错

System.InvalidOperationException:"The property 'Moment.LableID' cannot be marked as nullable/optional because the type of the property is 'ulong' which is not a nullable type. Any property can be marked as non-nullable/required, but only properties of nullable types can be marked as nullable/optional."

cs 复制代码
modelBuilder.Entity<Moment>().Property(x=>x.LableID).IsRequired(false);
modelBuilder.Entity<Moment>().Property(x => x.Lable).IsRequired(false);

改进代码V2

删除上两行配置

cs 复制代码
modelBuilder.Entity<Moment>().HasOne(x => x.Lable).WithMany(x => x.Moments).HasForeignKey(x => x.LableID).IsRequired(false);

运行依然报错:FOREIGN KEY constraint failed

改进代码V3

保留V2,将Lable加个?,可空标记。

cs 复制代码
 public class Moment
 {
     public ulong MomentID {  get; set; }
     public string Content { get; set; } = string.Empty;

     public ulong? LableID {  get; set; }
 
     public Lable Lable { get; set; }    
 }

运行成功

查看数据库字段,已允许为Null了

结语

坑我好几天......不是专业后端......

搜博客翻墙,关键字HasForeignKey,IsRequired 都没找对方法。

谁知道就是缺个?

一键三连

如果可以帮助到你,记得一键三连。

点赞·评论·留言

大家的支持,即是我协作的动力,

或者可以请我喝杯咖啡哦

相关推荐
fictionist40 分钟前
正则表达式篇
linux·运维·服务器·数据库·mysql·正则表达式·c#
lzjava20241 小时前
SQL解析工具JSQLParser
java·数据库
文牧之1 小时前
Oracle 的 MOVE 操作是否重建表?
运维·数据库·oracle
数据要素X2 小时前
【数据架构06】可信数据空间架构篇
大数据·运维·数据库·人工智能·架构
江畔柳前堤2 小时前
PyQt学习系列10-性能优化与调试技巧
开发语言·javascript·数据库·学习·性能优化·ecmascript·pyqt
代码配咖啡2 小时前
深度解析:SQLynx 如何筑牢数据库安全防线
开发语言·数据库·php
阳光九叶草LXGZXJ2 小时前
达梦数据库-学习-21-C 外部函数
linux·运维·c语言·开发语言·数据库·sql·学习
Monly212 小时前
MySQL:备份还原数据库(mysqldump)
数据库·mysql
元亓亓亓2 小时前
MySQL--day6--单行函数
android·数据库·mysql
涛思数据(TDengine)2 小时前
时序数据库 TDengine × Superset:一键构建你的可视化分析系统
数据库·时序数据库·tdengine