EF Core一对多与FK



一个Document可以包含多个Images;一个Image只能引用一个Document:

CREATE TABLE [Images] 
(
[Id] [bigint] NOT NULL IDENTITY(1,1),
...
[DocumentId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Images_Id] 
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Images_Documents] 
FOREIGN KEY([DocumentId]) REFERENCES [Documents]([Id])
)
CREATE TABLE [Documents] 
(
[Id] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
...
[DocumentId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Documents_Id] 
PRIMARY KEY CLUSTERED ([Id] ASC),
...
)

c#类:

public class Image
{
public long Id {get; set;}
public string Name {get; set;}
...
public Document Document { get; set; }
}
public class Document
{
public Guid Id {get; set;}
public string Name {get; set;}
....
public ICollection<Image>? Images { get; set; } = new List<Image>();
}

最后是映射

public class ImageConfiguration : IEntityTypeConfiguration<Image>
{
public void Configure(EntityTypeBuilder<Image> builder)
{
builder.HasKey(it => it.Id);   
....      
builder.HasOne(it => it.Document).WithMany(c => c.Images);
}
}

当我尝试插入DocumentImage时:

var document = new Document
{
Name = "Test doc",
Images = new List<Image>{new Image{ Name = "test"}};
};
var db = new MyDbContext();
db.Documents.Add(document);
db.SaveChanges();

我得到这个错误:

Microsoft.EntityFrameworkCore。DbUpdateException:保存实体更改时发生错误。
详情请参阅内部异常。

Microsoft.Data.SqlClient。sql异常:INSERT语句与外键约束冲突"FK_Images_Documents".

冲突发生在数据库"mydb"、表"文档"、列"Id"中。

如果我为图像更改创建表脚本,并使属性DocumentId为NULL,并删除相应的FK (FK_Images_Documents),并将Document标记为Image模型上的可空值,则插入(文档和图像)将成功通过。

我做错了什么?

您的配置一团糟。您可能已经定义了一个额外的外键属性。所以删除你的流畅配置,重新开始。

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
namespace EfCore6Test
{
public class Image
{
public long Id { get; set; }
public string Name { get; set; }

public Document Document { get; set; }
}
public class Document
{
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<Image>? Images { get; set; } = new List<Image>();
}
public class Db : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Document>();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=localhost;database=efCore6Test;Integrated Security=true;TrustServerCertificate=true", o => o.UseRelationalNulls(true))
.LogTo(Console.WriteLine, LogLevel.Information);
base.OnConfiguring(optionsBuilder);
}
}

class Program
{
static void Main(string[] args)
{
using (var db = new Db())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var document = new Document()
{
Name = "Test doc",
Images = new List<Image> { new Image { Name = "test" } }
};
db.Set<Document>().Add(document);
db.SaveChanges();
}
}
}
}

关于"注意力测试"的好问题:)

当我尝试执行这个示例时,得到以下错误:

SqlException: Cannot insert the value NULL into column 'DocumentId', table 'testDb.dbo.Documents'; column does not allow nulls. INSERT fails.

原因是当你创建db-table Documents时:

CREATE TABLE [Documents] 
(
[Id] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
...
[DocumentId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Documents_Id] 
PRIMARY KEY CLUSTERED ([Id] ASC),
...
)

我想你偶尔会添加过多的列" documententid& quot;到db-table Documents not null(但您已经在那里定义了Id主键列),这不会得到set

var document = new Document
{
Name = "Test doc",
Images = new List<Image>{new Image{ Name = "test"}};
};

所以我们有一个Documents db-table的不可空列documententid没有被设置,所以错误发生的预期行为

为避免以上错误,请删除多余的"文档编号";列

相关内容

  • 没有找到相关文章

最新更新