我有这个类结构:
公共类活动 {
[Key] public long ActivityId { get; set; } public string ActivityName { get; set; } public virtual HashSet<ActivityLogMessage> ActivityLogMessages { get; set; } public virtual HashSet<FileImportLogMessage> FileImportLogMessages { get; set; } public virtual HashSet<RowImportLogMessage> RowImportLogMessages { get; set; } } public abstract class LogMessage { [Required] public string Message { get; set; } public DateTimeOffset CreateDate { get; set; } [Required] public long ActivityId { get; set; } public virtual Activity Activity { get; set; } } public class ActivityLogMessage : LogMessage { public long ActivityLogMessageId { get; set; } } public class FileImportLogMessage : ActivityLogMessage { public long? StageFileId { get; set; } } public class RowImportLogMessage : FileImportLogMessage { public long? StageFileRowId { get; set; } }
这给了我这个,型号
每条消息(活动,文件或行)必须与活动相关联。为什么第二级和第三级与ActivityLogMessage没有相同的基数?我试图描述外键关系(通过模型构建者流利)也失败了。
这对我来说真的是一个学术练习,可以真正理解EF如何映射到关系,这让我感到困惑。
此致 理查德
答案 0 :(得分:1)
EF使用不可为空的外键属性Activity.ActivityLogMessages
推断出一对导航属性ActivityLogMessage.Activity
和ActivityLogMessage.ActivityId
,因此关系被定义为必需。
其他两个关系来自馆藏Activity.FileImportLogMessages
和Activity.RowImportLogMessages
。它们既没有反向导航属性,也没有外键属性,默认情况下会导致可选关系。
您可能希望LogMessage.Activity
和LogMessage.ActivityId
用作所有三个集合的反向属性。但它不会这样。 EF不能在多个关系中使用相同的导航属性。此外,您当前的模型意味着RowImportLogMessage
例如与Activity
有三个关系,而不仅仅是一个。
我相信如果删除馆藏,你会更接近你想要的东西:
public virtual HashSet<FileImportLogMessage> FileImportLogMessages { get; set; }
public virtual HashSet<RowImportLogMessage> RowImportLogMessages { get; set; }
您仍然可以通过派生类型过滤剩余的ActivityLogMessages
(例如,在仅具有getter的未映射属性中):
var fileImportLogMessages = ActivityLogMessages.OfType<FileImportLogMessage>();
// fileImportLogMessages will also contain entities of type RowImportLogMessage
var rowImportLogMessage = ActivityLogMessages.OfType<RowImportLogMessage>();