需求:
发表动态可以没有标签,允许导航属性为空。
现象:
使用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 都没找对方法。
谁知道就是缺个?
一键三连
如果可以帮助到你,记得一键三连。
点赞·评论·留言
大家的支持,即是我协作的动力,
或者可以请我喝杯咖啡哦