EF5,继承FK和基数

时间:2013-08-02 18:24:50

标签: entity-framework cardinality

我有这个类结构:

  

公共类活动       {

    [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; }
}

这给了我这个,型号

EF5 Entity Model

每条消息(活动,文件或行)必须与活动相关联。为什么第二级和第三级与ActivityLogMessage没有相同的基数?我试图描述外键关系(通过模型构建者流利)也失败了。

这对我来说真的是一个学术练习,可以真正理解EF如何映射到关系,这让我感到困惑。

此致 理查德

1 个答案:

答案 0 :(得分:1)

EF使用不可为空的外键属性Activity.ActivityLogMessages推断出一对导航属性ActivityLogMessage.ActivityActivityLogMessage.ActivityId,因此关系被定义为必需。

其他两个关系来自馆藏Activity.FileImportLogMessagesActivity.RowImportLogMessages。它们既没有反向导航属性,也没有外键属性,默认情况下会导致可选关系。

您可能希望LogMessage.ActivityLogMessage.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>();