0

我有这个类结构:

公共类活动{

    [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 实体模型

每条消息(活动、文件或行)都必须与活动相关联。为什么 2nd 和 3rd 级别的基数与 ActivityLogMessage 不同?我描述外键关系的尝试(通过模型构建器流畅)也失败了。

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

问候,理查德

4

1 回答 1

1

EF 推断出一对导航属性Activity.ActivityLogMessagesActivityLogMessage.Activity一个不可为空的外键属性ActivityLogMessage.ActivityId,因此根据需要定义关系。

其他两个关系是从集合Activity.FileImportLogMessages和推断出来的Activity.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>();
于 2013-08-02T18:57:23.653 回答