Поскольку это довольно экзотическая ситуация, для этого нет встроенной поддержки. Но вы можете заставить его выглядеть красиво.
Пока у вас есть нечто подобное, если предположить, что ваша таблица соединений называется E1E2.
public partial class E1
{
public Guid Id { get; set; }
public IQueryable<E1E2> Stack { get; }
}
public partial class E2
{
public Guid Id { get; set; }
public IQueryable<E1E2> In { get; }
}
public partial class E1E2
{
public E1 E1 { get; set; }
public E2 E2 { get; set; }
public Int32 Position { get; set; }
}
Как раз я не могу придумать лучшего решения для сопоставления этого с базой данных. Чтобы сделать использование максимально разумным, просто добавьте некоторые свойства и методы к сущностям. Это легко, потому что объект создает частичные классы.
Расширить класс E1 следующим образом.
public partial class E1
{
public IQueryable<E2> NiceStack
{
get { return this.Stack.Select(s => s.E2).OrderBy(s => s.Position); }
}
public void Push(E2 e2)
{
this.Stack.Add(
new E1E2
{
E2 = e2,
Position = this.Stack.Max(s => s.Position) + 1
});
}
public E2 Pop()
{
return this.Stack.
Where(s => s.Position == this.Stack.Max(s => s.Position).
Select(s => s.E2).
Single();
}
}
Расширить класс E2 следующим образом.
public partial class E2
{
public IQueryable<E1> NiceIn
{
get { return this.In.Select(i => i.E1); }
}
public IQueryable<E1> NiceTop
{
get
{
return this.In.
Where(i => i.Position == i.E1.Stack.Max(s => s.Position)).
Select(i => i.E1);
}
}
}
Конец, ты здесь. Теперь должно быть возможно написать довольно хороший код вокруг этой сущности. Возможно, в коде есть некоторые ошибки, но идея должна быть ясной. Я пропустил код, чтобы гарантировать, что связанные свойства загружаются при доступе. Кроме того, вы можете сделать оригинальную собственность приватной и скрыть ее снаружи. Возможно, вам не следует включать свойство NiceStack, потому что это разрешает произвольный доступ. Или, может быть, вы хотите добавить больше расширений - возможно, сделать NiceTop доступным для записи, помещая экземпляр E2 в стек экземпляра E1, вставленного в NiceTop экземпляра E2. Но идея остается прежней.
Вызов Single () не будет работать с обычной Entity Framework; вместо этого используйте ToList (). Single (), чтобы переключиться на LINQ to Object, или используйте First (), но first не сохраняет семантику ровно одного.