Modeling related entities with SQL Server and entity framework
I've got a table in my database stor开发者_StackOverflow社区ing items:
Items
-------
ItemID
Name
...
Etc
and a separate table storing the PK of two different items from the first table. I want to be able to list the one item, and then any number of related items. I've tried searching for examples but haven't found much surprisingly...
RelatedItems
------------
ItemID
RelatedItemID
If I have four products, whose IDs are 1, 2, 3 and 4... and 1 is related to 2 and 3 I might have data that looks like this:
ItemID RelatedItemID
1 2
1 3
4 1
I am then modeling them in the Entity Framework Designer, and the designer automatically adds an association from the Items table to itself (many to many). The designer also adds two navigation properties, if I use the first property on Item #1 I get all items where Item #1 is in the first column, and if I use the second property I get all the items where Item #1 is in the second column.
I however just want to have one navigation property where I can say Items.RelatedItems and it returns all the items that the above two properties would when combined. I know I can join the two results after the fact but I can't help to think I'm doing something wrong and there is a better way.
Hopefully this is all clear enough.
It sounds like SQL schemas just aren't very good at modeling the concept you're looking for. The schema you've chosen would work well if you want to establish a directional relationship (item A is related to item B, but item B may or may not be related to item A). If you were looking for a grouping-style relationship (Items A and B are in the same group), I can think of a different approach you'd use. But I can't think of a good way to model an inherently bi-directional relationship using a traditional relational database.
Some workarounds might be to use a View that joins the two results, or to use triggers to make sure that every mapping from A to B has a corresponding mapping from B to A, so that both of the properties always return the same objects.
If you have an instance of an Item, call it item, then the following will give you the related items...
item.RelatedItems.Select(ri => ri.Item);
Your RelatedItems property on item (ie the first navigation property you mentioned) will be a collection of RelatedItem objects, each of which has two navigation properties of its own, one of which will be named Item and will be a link to the related item.
Note that this is air code, as I'm not in front of anything I can test this on right now, but I think this will do what you want.
If you want to make it simpler, you can write an extension method to wrap up the Select(), something like this...
public static IEnumerable<Item> RelItems(this Item item) {
return item.RelatedItems.Select(ri => ri.Item);
}
Then you could just do...
item.RelItems();
Note that I couldn't name the extension method RelatedItems, as that would clash with the navigation property that EF would have created for the second table. That's perhaps not a good name for that tables, as it's not the actual items, rather the IDs of the items. Either way, the above code should work.
精彩评论