简体   繁体   English

EntityFramework Core:Model,使用映射表收集相同类型的对象

[英]EntityFramework Core: Model with collection of objects of the same type using mapping table

Hoping someone might be able to answer this as I am struggling to find a decent answer.希望有人能够回答这个问题,因为我正在努力寻找一个像样的答案。 It's been a while since I've poked around with EF, especially the core variant.自从我研究 EF 以来已经有一段时间了,尤其是核心变体。

Basically given the following 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]))

Then I have a model of:然后我有一个 model 的:

public class Document {
    public long Id { get; set; }
    public IEnumerable<Document> DependentDocuments { get; set; }
}

The relationship being defined as, one document can have 0 or more dependent documents as defined by the mapping table.关系被定义为,一个文档可以有 0 个或多个依赖文档,如映射表所定义的那样。 However I am unable to find a way of mapping this in EFCore without having to create a new object for the DependentDocument which I'd rather not do.但是,我无法找到一种在 EFCore 中映射它的方法,而不必为 DependentDocument 创建一个新的 object,我不想这样做。

Any-one got any ideas?有人有什么想法吗? Thanks.谢谢。 Tried searching for an appropriate answer but can't find anything that really matches it.尝试搜索合适的答案,但找不到真正匹配的答案。 Perhaps my architecture is wrong but no harm asking for other opinions.也许我的架构是错误的,但征求其他意见也无妨。

[Updates] After some digging around and messing with implementations based on Martinauts answer below I came up with this: [更新] 在根据下面的 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");
                });
    }
}

using the above configuration alone it does not work unfortunately.不幸的是,仅使用上述配置是行不通的。 However, if I then add the NuGet Package Microsoft.EntityFrameworkCore.Proxies and enable LazyLoading, it does indeed retrieve the dependency documents, however only for the Inverse collection.但是,如果我随后添加 NuGet Package Microsoft.EntityFrameworkCore.Proxies 并启用 LazyLoading,它确实会检索依赖文档,但仅限于反向集合。 Anyone got any clue why it won't work without lazy loading?任何人都知道为什么没有延迟加载它就不能工作? I've tried enumerating the lists to get the associated documents but it doesn't seem to work without that LazyLoading feature enabled on the context.我已经尝试枚举列表以获取关联的文档,但如果没有在上下文中启用 LazyLoading 功能,它似乎无法工作。

[Update #2] Actually got it working, so the code works as per suggested answer but need to remember to include the dataset as well:/ [更新#2] 实际上让它工作了,所以代码按照建议的答案工作,但需要记住也包括数据集:/

Add the InverseDependentDocuments property to the Document -class.InverseDependentDocuments属性添加到Document类。

public class Document {
    public long Id { get; set; }
    public IEnumerable<Document> DependentDocuments { get; set; } 
    public IEnumerable<Document> InverseDependentDocuments { get; set; } 
}

You can configure the relationship using the model builder in your DbContext class in the OnModelCreating method:您可以在OnModelCreating方法中使用DbContext class 中的 model 构建器配置关系:

modelBuilder.Entity<Document>
    .HasMany(x => x.DependentDocuments)
    .WithMany(x => x.InverseDependentDocuments)
    .usingEntity(x => {
       x.ToTable("DocumentDependencies")
       // ... additional configuration for column naming
    });

This is also explained in the documentation . 文档中也对此进行了解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM