首页 > 解决方案 > EF Core - 为多个关系重用相同的连接表实体

问题描述

我想为其他几个对象(课程、讲座、游戏)重用相同的多对多关系表(FileInEntity),因为它们都可以有文件。由于我们必须通过创建连接实体来手动创建多对多关系,因此我想为对象(课程、讲座、游戏)重用连接实体。

如果我们看一下表结构,我想有以下内容:

课程:身份证,...

讲座:身份证,...

游戏:身份证,...

FileInEntity:EntityId(可以是 Course.Id、Lecture.Id 或 Game.Id)、FileId

File : Id, ... (文件是基类类型,具有两种派生类型:图像和音频)

当我在 .NET Core 中尝试这种方法时,我收到以下错误消息:

实体类型“FileInEntities”处于阴影状态。一个有效的模型要求所有实体类型都有对应的 CLR 类型。

这甚至可能吗?


这是我的设置:

模型库.cs

public class ModelBase
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
}

课程.cs

[Table("Courses")]
public class Course : ModelBase
{
    private ICollection<FileInEntity> IconsInCourse { get; set; } = new List<FileInEntity>();

    [NotMapped]
    public File Image => IconsInCourse.Select(e => e.File).FirstOrDefault();
}

讲座.cs

// Same as Course.cs

游戏.cs

// Same as Course.cs

FileInEntity.cs

[Table("FilesInEntities")]
public class FileInEntity
{
    public Guid FileId { get; set; }

    public Guid EntityId { get; set; }

    public virtual ModelBase Entity { get; set; }

    public virtual File File { get; set; }
}

文件.cs

[Table("Files")]
public class File : ModelBase
{
    // This is the property for which the error occured
    private ICollection<FileInEntity> FileInEntities { get; set; } = new List<FileInEntity>();

    public IEnumerable<ModelBase> Entities => FileInEntities.Select(e => e.Entities);
}

FilesInEntitiesMap.cs(关系配置)

builder.HasOne(p => p.Entity)
    .WithMany()
    .HasForeignKey(k => k.EntityId);

builder.HasOne(p => p.File)
    .WithMany()
    .HasForeignKey(k => k.FileId);

文件映射.cs

// This is the key to which the error references to
builder.HasMany("FileInEntities")
    .WithOne("Entity")
    .HasForeignKey("EntityId");

标签: c#asp.net-coreentity-framework-core

解决方案


您将无法使用基类 ModelBase 作为映射类中的对象,因为 c# 不会知道从数据库返回的实际类型。您可以查看每个层次结构继承的表,但我仍然不确定您是否能够在映射表中使用它。 这是一篇好文章

如果您的 Course.cs、Lecture.cs 和 Game.cs 相同,并且唯一的区别是类型,您可以将它们合并为一个类并添加一个枚举属性来设置类型。

public enum EntityType{
    Game = 1,
    Lecture = 2,
    Course = 3
}

public class MyEntity : ModelBase{
    private ICollection<FileInEntity> Icons { get; set; } = new List<FileInEntity>();

    [NotMapped]
    public File Image => Icons.Select(e => e.File).FirstOrDefault();

    public EntityType EntityType {get;set;} //course, lecture, or  game
}

当您关心类型时,只需使用 where 子句。


推荐阅读