需求:
发表动态可以没有标签,允许导航属性为空。
现象:
使用EFCore库框架,添加数据时出现。
截图:
数据表
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; } }
public class Lable{public ulong LableID { get; set; }public string Name { get; set; } = string.Empty;public List<Moment> Moments { get; set; }}
DbContext
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插入数据代码
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.”
modelBuilder.Entity<Moment>().Property(x=>x.LableID).IsRequired(false);
modelBuilder.Entity<Moment>().Property(x => x.Lable).IsRequired(false);
改进代码V2
删除上两行配置
modelBuilder.Entity<Moment>().HasOne(x => x.Lable).WithMany(x => x.Moments).HasForeignKey(x => x.LableID).IsRequired(false);
运行依然报错:FOREIGN KEY constraint failed
改进代码V3
保留V2,将Lable加个?,可空标记。
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 都没找对方法。
谁知道就是缺个?
一键三连
如果可以帮助到你,记得一键三连。
点赞·评论·留言
大家的支持,即是我协作的动力,
或者可以请我喝杯咖啡哦