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

Каждое сообщение (действие, файл или строка) должно быть связано с действием. Почему 2-й и 3-й уровень не имеют такой же мощности, как ActivityLogMessage ? Мои попытки описать отношения внешнего ключа (свободно через конструктор моделей) также не увенчались успехом.

Это действительно академическое упражнение для меня, чтобы действительно понять, как EF сопоставляется с реляционными, и это меня смущает.

С уважением, Ричард


person codeputer    schedule 02.08.2013    source источник


Ответы (1)


EF выводит пару свойств навигации Activity.ActivityLogMessages и ActivityLogMessage.Activity со свойством внешнего ключа ActivityLogMessage.ActivityId, которое не может принимать значение NULL, поэтому отношения определяются как требуемые.

Два других отношения выводятся из коллекций 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 по производным типам (например, в несопоставленных свойствах, которые имеют только геттер):

var fileImportLogMessages = ActivityLogMessages.OfType<FileImportLogMessage>();
// fileImportLogMessages will also contain entities of type RowImportLogMessage

var rowImportLogMessage = ActivityLogMessages.OfType<RowImportLogMessage>();
person Slauma    schedule 02.08.2013