Может ли EF4.1 Code First одновременно выразить 1-1 и 1-много в одной и той же таблице?
Проблема высокого уровня: я хотел бы получить быстрый поиск по таблице, к которой у меня отношение 1-многие.
У меня есть большая журнальная таблица с внешним ключом для таблицы сотрудников. Я хотел бы иметь отношение из таблицы сотрудников к самой последней записи в журнале (для этого сотрудника), а также к регулярной коллекции многих записей журнала. Я мог бы использовать только один ко многим и просто запросить последнюю метку времени и идентификатор сотрудника в лог-файле, но я бы предпочел прямой указатель.
Можно ли сделать что-то подобное с аннотациями?
public class TagEntry
{
public int TagEntryId { get; set; }
public int TagId { get; set; }
public DateTime LogTime { get; set; }
public string log { get; set; }
public virtual Tag tag { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public TagEntry CurrentTagEntry { get; set; }
public int TagEntryId { get; set; }
public string someTagData { get; set; }
public virtual ICollection<TagEntry> TagEntries { get; set; }
}
Одним из решений было бы просто сохранить целочисленный currentTagEntryId, но в идеале я бы хотел сослаться на Log с нотацией типа tag.CurrentTagEntry.log.
1 ответ
К сожалению, это невозможно с помощью картографирования. Ваш CurrentTagEntry
представляет один к одному отношения между Tag
а также TagEntry
но в то же время у вас есть отношение один ко многим между Tag
а также TagEntry
, Сопоставление один-к-одному требует, чтобы оба объекта совместно использовали первичный ключ =>, чтобы иметь возможность отображать отношения один-к-одному. PK TagEntry должен быть FK для Tag
, Это, очевидно, нарушит отношение один ко многим.
Вы должны сделать это как вспомогательную функцию вместо отображения.
Например, это можно использовать как вспомогательный запрос linq:
var lastLog = (from te in context.TagEntries
where te.TagId == id
orderby te.LogTime descending
select te).FirstOrDefault();
Или это как вспомогательная загрузка:
var entry = context.Entry<Tag>(tag);
if (!entry.Collection(t => t.TagEntries).IsLoaded)
{
// Selective eager loading
entry.Collection(t => t.TagEntries)
.Query()
.OrderByDescending(te => te.LogTime)
.Take(1)
.Load();
}
var tag = tag.TagEntries.FirstOrDefault();