Rozpoznawanie typów poszczególnych elementów na liście

0

Huh, temat zawiły.
Więc tak. Mam sobie jakąś hierarchię dziedziczenia, np:

Item - bazowy
ItemA: Item
ItemB: Item
ItemC: ItemA

Każdy z tych itemów ma mieć możliwość zapisu do bazy danych, do pliku binarnego, do XMLa itd. Generalnie kilka formatów zapisu.
Skupmy się na bazie danych, bo najłatwiej będzie opisać problem.

Każdy z tych typów ma osobną tabelę w bazie danych. W aplikacji mają osobne repozytoria.

Mam metodę do zapisu, której sygnatura wygląda tak:

public void Save(IEnumerable<Item> items)

Po prostu dostaję listę elementów do zapisu.

I teraz pojawia się problem - w jaki sposób zapisać odpowiednie itemy do odpowiednich tabel?
Najprostszą metodą, jaka się narzuca od razu jest posegregowanie tych itemów na listy odpowiednich typów, np:

List<ItemA> itemsA = GetItemsOfType<ItemA>(items);
List<ItemB> itemsB = GetItemsOfType<ItemB>(items);

itd

Metoda GetItemsOfType po prostu iterowałaby listę itemsów i zwracała listę tylko tych, którym zgadza się typ. I tu pojawia się - być może - problem. Pomijam już kwestie wydajnościowe (kilkukrotna iteracja tej samej listy - chociaż lista może się zmniejszać z każdym wywołaniem metody), bo nie ma co optymalizować "na pałę", ale głównie chodzi mi o lampkę, która mi się zapala: "Hej, porównujesz typy, czy na pewno wszystko w porządku?"

Później te podlisty zapisywałbym za pomocą odpowiednich repozytoriów:

itemsARepository.SaveAll(itemsA);
itemsBRepository.SaveAll(itemsB);

itd.

To rozwiązanie wydaje mi się sensowne. Ale czy można to zrobić jakoś lepiej? Bez porównywania typów?

Myślałem o tym, żeby itemy miały atrybuty, które określałyby miejsce ich zapisu. Dla bazy danych byłaby to nazwa tabeli, dla XML nazwa sekcji itd:

[SaveTo("ItemsA")]
class ItemA: Item
{

}

ale to rozwiązanie wydaje mi się mało eleganckie, poza tym nie mam pojęcia, które byłoby lepsze.
A co Wy o tym sądzicie?

0

ILookup<Type, Item> look = items.ToLookup(x=>x.GetType());

        itemsARepositorySaveAll(look[typeof(ItemA)].Cast<ItemA>().ToList());
        itemsARepositorySaveAll(look[typeof(ItemB)].Cast<ItemB>().ToList());
0

O fajne rozwiązanie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1