You need to enter another collection inside the widget, something like.
public virtual ICollection<Widget> AdjacentFrom { get; set; } public virtual ICollection<Widget> AdjacentTo { get; set; }
By default, without the fluent-api configuration, this code will create the WidgetWidgets container WidgetWidgets in the database, which contains two columns Widget_Id and Widget_Id1 .
But you need to be consistent in order to use only one collection to create related relationships. If you use the AdjacentTo collection to create an adjacent relationship.
widget1.AdjacentTo.Add(widget2);
After saving widget1.AdjacentTo will be widget2 and widget2.AdjacentFrom will be widget1 .
Widget_Id Widget_Id1 2 1
But if you re-enter the AdjacentFrom collection to make an adjoining ratio.
widget1.AdjacentFrom.Add(widget2);
After saving widget1.AdjacentFrom and widget1.AdjacentTo will be widget2 . The same thing happens with widget2 .
Widget_Id Widget_Id1 2 1 1 2
A composite unique key cannot prevent the insertion of a second record because the second record is not considered a duplicate row. But there is a workaround, by adding a validation constraint, you can add this constraint to the migration.
Sql("alter table WidgetWidgets add constraint CK_Duplicate_Widget check (Widget_Id > Widget_Id1)");
To select all the neighboring ones, you can add another collection, something like.
[NotMapped] public ICollection<Widget> Adjacent { get { return (AdjacentFrom ?? new Widget[0]).Union((AdjacentTo ?? new Widget[0])).Distinct().ToArray(); } }
After adding a check constraint, you can use this extension to add or remove contiguous ones.
public static class WidgetDbExtension { public static void AddAdjacent(this Widget widget1, Widget widget2) { if (widget1.Id < widget2.Id) { widget1.AdjacentTo.Add(widget2); } else { widget2.AdjacentTo.Add(widget1); } } public static void RemoveAdjacent(this Widget widget1, Widget widget2) { if (widget1.Id < widget2.Id) { widget1.AdjacentTo.Remove(widget2); } else { widget2.AdjacentTo.Remove(widget1); } } }