繁体   English   中英

EF Core-将同一个联接表实体重用于多个关系

[英]EF Core - Reuse the same join table entity for several relationships

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

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

课程 :Id,...

讲座 :Id,...

游戏 :Id,...

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

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

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

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

这有可能吗?


这是我的设置:

模型库

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

Course.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();
}

Lecture.cs

// Same as Course.cs

Game.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; }
}

File.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);

FileMap.cs

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

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

如果您的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子句即可。

确保在DbContext's OnModelCreating使用Fluent Api为该表确定One to One relationship (并再次确保选择了正确的参考属性)

您的代码缺少部分。

public class ModelBase
{
    [Key]// add for primary key
    //set none always for primary keys (because guid has no auto increment)
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public Guid Id { get; set; }
}


[Table("Files")]
public class File : ModelBase
{
    //make it public
    public ICollection<FileInEntity> FileInEntities { get; set; } = new List<FileInEntity>(); 

    [NotMapped] //set not mapped
    public IEnumerable<ModelBase> Entities => FileInEntities.Select(e => e.Entities);

    //do it same changes for `Lacture.cs`, `Game.cs` and `Course.cs`...
}

暂无
暂无

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

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