c# - 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");
解决方案
您将无法使用基类 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 子句。
推荐阅读
- reactjs - Jest/Enzyme SVG Sprites 意外令牌 <
- c# - 使用模式工厂获取类型化对象
- aurelia - 数字格式转换后,Aurelia 不需要的字母出现在文本输入中。
- python - 如何使用 kubectl 在 pod 上调用事件
- ruby-on-rails - 图像未在 Heroku 中加载
- node.js - MongoDB - 查找没有父文档引用的记录
- android - AndroidX Dagger2 MultiDexApplication:不实现 HasActivityInjector
- python - 如何在af字符串表达式中将数字格式化为两位小数?
- c++ - 使用 wchar_t 更改字符类型不像 L
- servicestack - 内存中的 ServiceStack 客户端内存限制