Parce que c'est une situation assez exotique, il n'y a pas de support intégré pour cela. Mais vous pouvez le rendre joli.
Pour l'instant, vous avez quelque chose comme ça en supposant que votre table de jointure s'appelle E1E2.
public partial class E1
{
public Guid Id { get; set; }
public IQueryable Stack { get; }
}
public partial class E2
{
public Guid Id { get; set; }
public IQueryable In { get; }
}
public partial class E1E2
{
public E1 E1 { get; set; }
public E2 E2 { get; set; }
public Int32 Position { get; set; }
}
À l'heure actuelle, je ne peux pas trouver de meilleure solution pour mapper cela dans une base de données. Pour rendre l'utilisation aussi intelligente que possible, ajoutez simplement des propriétés et des méthodes aux entités. C'est facile car les entités sont générées comme des classes partielles.
Étendez la classe E1 comme suit.
public partial class E1
{
public IQueryable 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();
}
}
Étendez la classe E2 comme suit.
public partial class E2
{
public IQueryable NiceIn
{
get { return this.In.Select(i => i.E1); }
}
public IQueryable NiceTop
{
get
{
return this.In.
Where(i => i.Position == i.E1.Stack.Max(s => s.Position)).
Select(i => i.E1);
}
}
}
Et voilà. Maintenant, il devrait être possible d'écrire un code assez propre autour de ces entités. Il y a probablement des bogues dans le code mais l'idée devrait être claire. J'ai laissé de côté le code pour garantir que les propriétés liées sont chargées lors de leur accès. Vous pourriez rendre les propriétés originales privées et les masquer de l'extérieur. Peut-être ne devriez-vous pas inclure la propriété NiceStack car cela permet un accès aléatoire. Ou peut-être voulez-vous ajouter plus d'extensions - peut-être rendre NiceTop inscriptible en poussant une instance de E2 sur la pile d'une instance de E1 insérée dans NiceTop de l'instance de E2. Mais l'idée reste la même.
L'appel à Single() ne fonctionnera pas avec l'Entity Framework normal; utilisez plutôt ToList().Single() pour passer à LINQ to Object ou utilisez First() mais First ne préserve pas la sémantique de un seul élément.