2013-08-02 28 views
0

我有这样的阶级结构:EF5,继承FK和基数

公共类活动 {

[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

每个消息(活动,文件或行)必须具备e与一个活动相关联。为什么第二级和第三级不具有与ActivityLogMessage相同的基数?我尝试描述外键关系(通过modelbuilder流利)也失败了。

这真是一个学术练习,让我真正理解EF如何映射到关系,这使我感到困惑。

问候, 理查德

回答

1

EF推断一对导航属性Activity.ActivityLogMessagesActivityLogMessage.Activity的带有外键属性ActivityLogMessage.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>();