Hej på er, Det har ju egentligen inte med NHibernate att göra. Du får exakt samma problematik när du ska instansera ett nytt objekt, och du inte i förväg vet typen på item. Jag hade nog tänkt om designen och haft en basklass/interface för item eller något ditåt. Jag var också inne på det spåret men hur laddar jag ett item av okänd typ? Nu har jag hittat en lösning som jag är någolunda nöjd med. Faktum kvarstår ju att du måste veta typen i något skede, om du inte använder ett interface eller basklass. Om du inte vill göra: Tack, lösningen jag kom fram till till sist var att ha:Nhibernate: Generisk länkning?
jag har en basklass som jag kallar Base och flera olika klasser som ska länka till denna (eller ärva den, spelar ingen roll).
Nu är det ju inte så svårt att mappa en child-klass till Basklassen i NHibernate, jag skapar bara en many-to-one relation.
Men hur mappar jag från basklassen till korrekt child-klass? Är det ens möjligt?
Exempel:
Base<T>:
int Id
string Name
string Type
T item
Childclass:
Id
Base<Childclass> Base
[other non-relevant info]
Flera child-klasser ska inte kunna länka till en och samma Base utan det ska alltså finnas en Base per child. Det finns dock flera olika typer av childklasser.
Problemet är att jag inte kan veta typen på item innan jag laddat Base-objektet men jag kan inte ladda base objektet utan att veta typen?Sv: Nhibernate: Generisk länkning?
Sv:Nhibernate: Generisk länkning?
Om jag t.ex. som i exemplet ovan har en baseklass och en childklass hur laddar jag då endast basklassen? (Eftersom jag inte kan veta childklassen innan jag vet basklassens "type").
Ett till exempel för att förtydliga vad jag vill göra.
Jag har en basklass som heter item:
Id
Name
Type
Och en childklass som heter Page
Id
Item (Länk till basklassen)
Content
Layout
Från början vet jag endast Name och vill utifrån det först ta reda på typen och sedan ladda rätt typ, i det här fallet Page.Sv: Nhibernate: Generisk länkning?
Jag har en metod som jag vill använda för att ladda korrekt child:
<code>
public T GetSpecializedByItem<T>(Item item)
{
return _session.CreateCriteria(typeof(T))
.Add(Expression.Eq("Item", item))
.UniqueResult<T>();
}
</code>
Nu är frågan hur jag använder den här metoden.
Är det möjligt att göra något i stil med
<code>
Type childType = Type.GetType(item.Type);
childType child = GetSpecializedByItem<childType>(item);
</code>
(Ovanstående kod fungerar förstås inte men är det möjligt att göra något sånt?Sv:Nhibernate: Generisk länkning?
<code>
Type childType = Type.GetType(item.Type);
object child = GetSpecializedByItem<childType>(item);
</code>
Men det beror ju väldigt mycket på hur du sedan vill använda objektet.
Utan att veta speciellt mycket så hade jag nog skapat en abstrakt basklass, ärvt den för alla specialtyper, och sedan låtit NHibernate sköta instanseringen baserat på någon flagga som anger typen.Sv: Nhibernate: Generisk länkning?
Item:
int Id
string Name
string Type
Page:
int Id
Item Item
<code>
item = itemRepository.LoadItemByName();
switch(item.Type)
{
case "Page" :
Page page = itemRepository.Specialize<Page>(item);
}
</code>
Till slut kom jag fram till att det var bättre för min slutgiltiga lösning.
Exemplet ovan är något förenklat. Egentligen laddar jag i switchen en usercontrol och kör sedan i uc'n Specialize-funktionen.