EntityFramework 核心:使用映射对同一类型的对象集合进行建模 table
EntityFramework Core: Model with collection of objects of the same type using mapping table
希望有人能够回答这个问题,因为我正在努力寻找一个合适的答案。我已经有一段时间没有研究 EF 了,尤其是核心变体。
基本给出以下tables:
CREATE TABLE [Documents] (
[Id] BIGINT NOT NULL IDENTITY(1,1),
[Name] NVARCHAR(255) NOT NULL,
CONSTRAINT [PK_Documents] PRIMARY KEY CLUSTERED ([Id] ASC))
CREATE TABLE [DocumentDependencies] (
[DocumentId] BIGINT NOT NULL,
[DependentOnDocumentId] BIGINT NOT NULL,
CONSTRAINT [PK_DocumentDependencies] PRIMARY KEY CLUSTERED ([DocumentId] ASC, [DependentOnDocumentId] ASC),
CONSTRAINT [FK_DocumentDependencies_Documents] FOREIGN KEY ([DocumentId]) REFERENCES [Documents]([Id]),
CONSTRAINT [FK_DocumentDependencies_DocumentDependencies] FOREIGN KEY ([DependentOnDocumentId]) REFERENCES [Documents]([Id]))
那么我有一个模型:
public class Document {
public long Id { get; set; }
public IEnumerable<Document> DependentDocuments { get; set; }
}
关系定义为,一个文档可以有 0 个或多个依赖文档,如映射 table 所定义。
但是,我无法找到一种在 EFCore 中映射它的方法,而不必为 DependentDocument 创建一个我不想做的新对象。
有人有什么想法吗?谢谢。
尝试搜索合适的答案,但找不到真正匹配的答案。也许我的架构是错误的,但征求其他意见也无妨。
[更新]
在根据下面的 Martinauts 答案进行一些挖掘和搞乱实现之后,我想到了这个:
public class DocumentEntityTypeConfiguration : IEntityTypeConfiguration<Document>
{
public void Configure(EntityTypeBuilder<Document> builder)
{
builder.ToTable("Documents");
builder.HasKey(e => e.Id); js));
builder.HasMany(d => d.DependentDocuments)
.WithMany(p => p.InverseDependentDocuments)
.UsingEntity<Dictionary<string, object>>(
"DependentDocument",
r => r
.HasOne<Document>()
.WithMany()
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_MainDocument"),
l => l
.HasOne<Document>()
.WithMany()
.HasForeignKey("DependentDocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_DependentDocument"),
j =>
{
j.HasKey("DocumentId", "DependentDocumentId");
j.ToTable("DependentDocuments");
});
builder.HasMany(d => d.InverseDependentDocuments)
.WithMany(p => p.DependentDocuments)
.UsingEntity<Dictionary<string, object>>(
"DependentDocument",
r => r
.HasOne<Document>()
.WithMany()
.HasForeignKey("DependentDocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_DependentDocument"),
l => l
.HasOne<Document>()
.WithMany()
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_MainDocument"),
j =>
{
j.HasKey("DocumentId", "DependentDocumentId");
j.ToTable("DependentDocuments");
});
}
}
不幸的是,仅使用上述配置是行不通的。
但是,如果我随后添加 NuGet 包 Microsoft.EntityFrameworkCore.Proxies 并启用 LazyLoading,它确实会检索依赖文档,但仅限于反向集合。任何人都知道为什么没有延迟加载它就不能工作?我已经尝试枚举列表以获取相关文档,但如果没有在上下文中启用 LazyLoading 功能,它似乎无法工作。
[更新#2]
实际上让它工作了,所以代码按照建议的答案工作,但需要记住也包括数据集:/
将 InverseDependentDocuments
属性 添加到 Document
-class。
public class Document {
public long Id { get; set; }
public IEnumerable<Document> DependentDocuments { get; set; }
public IEnumerable<Document> InverseDependentDocuments { get; set; }
}
您可以在 DbContext
class 的 OnModelCreating
方法中使用模型构建器配置关系:
modelBuilder.Entity<Document>
.HasMany(x => x.DependentDocuments)
.WithMany(x => x.InverseDependentDocuments)
.usingEntity(x => {
x.ToTable("DocumentDependencies")
// ... additional configuration for column naming
});
这在documentation中也有解释。
希望有人能够回答这个问题,因为我正在努力寻找一个合适的答案。我已经有一段时间没有研究 EF 了,尤其是核心变体。
基本给出以下tables:
CREATE TABLE [Documents] (
[Id] BIGINT NOT NULL IDENTITY(1,1),
[Name] NVARCHAR(255) NOT NULL,
CONSTRAINT [PK_Documents] PRIMARY KEY CLUSTERED ([Id] ASC))
CREATE TABLE [DocumentDependencies] (
[DocumentId] BIGINT NOT NULL,
[DependentOnDocumentId] BIGINT NOT NULL,
CONSTRAINT [PK_DocumentDependencies] PRIMARY KEY CLUSTERED ([DocumentId] ASC, [DependentOnDocumentId] ASC),
CONSTRAINT [FK_DocumentDependencies_Documents] FOREIGN KEY ([DocumentId]) REFERENCES [Documents]([Id]),
CONSTRAINT [FK_DocumentDependencies_DocumentDependencies] FOREIGN KEY ([DependentOnDocumentId]) REFERENCES [Documents]([Id]))
那么我有一个模型:
public class Document {
public long Id { get; set; }
public IEnumerable<Document> DependentDocuments { get; set; }
}
关系定义为,一个文档可以有 0 个或多个依赖文档,如映射 table 所定义。 但是,我无法找到一种在 EFCore 中映射它的方法,而不必为 DependentDocument 创建一个我不想做的新对象。
有人有什么想法吗?谢谢。 尝试搜索合适的答案,但找不到真正匹配的答案。也许我的架构是错误的,但征求其他意见也无妨。
[更新] 在根据下面的 Martinauts 答案进行一些挖掘和搞乱实现之后,我想到了这个:
public class DocumentEntityTypeConfiguration : IEntityTypeConfiguration<Document>
{
public void Configure(EntityTypeBuilder<Document> builder)
{
builder.ToTable("Documents");
builder.HasKey(e => e.Id); js));
builder.HasMany(d => d.DependentDocuments)
.WithMany(p => p.InverseDependentDocuments)
.UsingEntity<Dictionary<string, object>>(
"DependentDocument",
r => r
.HasOne<Document>()
.WithMany()
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_MainDocument"),
l => l
.HasOne<Document>()
.WithMany()
.HasForeignKey("DependentDocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_DependentDocument"),
j =>
{
j.HasKey("DocumentId", "DependentDocumentId");
j.ToTable("DependentDocuments");
});
builder.HasMany(d => d.InverseDependentDocuments)
.WithMany(p => p.DependentDocuments)
.UsingEntity<Dictionary<string, object>>(
"DependentDocument",
r => r
.HasOne<Document>()
.WithMany()
.HasForeignKey("DependentDocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_DependentDocument"),
l => l
.HasOne<Document>()
.WithMany()
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentDocuments_MainDocument"),
j =>
{
j.HasKey("DocumentId", "DependentDocumentId");
j.ToTable("DependentDocuments");
});
}
}
不幸的是,仅使用上述配置是行不通的。 但是,如果我随后添加 NuGet 包 Microsoft.EntityFrameworkCore.Proxies 并启用 LazyLoading,它确实会检索依赖文档,但仅限于反向集合。任何人都知道为什么没有延迟加载它就不能工作?我已经尝试枚举列表以获取相关文档,但如果没有在上下文中启用 LazyLoading 功能,它似乎无法工作。
[更新#2] 实际上让它工作了,所以代码按照建议的答案工作,但需要记住也包括数据集:/
将 InverseDependentDocuments
属性 添加到 Document
-class。
public class Document {
public long Id { get; set; }
public IEnumerable<Document> DependentDocuments { get; set; }
public IEnumerable<Document> InverseDependentDocuments { get; set; }
}
您可以在 DbContext
class 的 OnModelCreating
方法中使用模型构建器配置关系:
modelBuilder.Entity<Document>
.HasMany(x => x.DependentDocuments)
.WithMany(x => x.InverseDependentDocuments)
.usingEntity(x => {
x.ToTable("DocumentDependencies")
// ... additional configuration for column naming
});
这在documentation中也有解释。