[C#] NHibernate en lege PersistentGenericBag<T>

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ik heb wat problemen met NHibernate waar ik niet uitkom. Ik koppel data aan een DataGridView met behulp van een BindingSource en het volgende probleem doet zich voor:

Als ik een lege PersistentGenericBag<T> terug krijg van NHibernate dan krijg ik deze NIET gebound aan een DataGridView. Een PersistentGenericBag<T> met tenminste 1 item krijg ik wel goed gebound. Ik heb gister wat interessante dingen gevonden.

Als ik run-time bekijk wat de IsDataBound property is van de DataGridViewTextBoxColumn dan:
1). Is deze FALSE wanneer ik een lege PersistentGenericBag<T> koppel aan de BindingSource
2). Is deze TRUE wanneer ik een nieuwe lege instantie van List<T> koppel aan de BindingSource
3). Is deze TRUE wanneer ik een niet-lege PersistentGenericBag<T> koppel aan de BindingSource

Wat ook interessant is, als ik alle kolommen in de DataGridView verwijder en AutoGenerateColumns op TRUE zet:
4). De DataGridView genereert GEEN kolommen voor een lege PersistentGenericBag<T>
5). De DataGridView genereert ALLE kolommen voor een nieuwe lege instantie van List<T>
6). De DataGridView genereert ALLE kolommen voor een niet-lege PersistentGenericBag<T>

Als ik de DataGridView documentatie voor AutoGenerateColumns bekijk dan zie ik dat er geen kolommen worden gegenereert als niet duidelijk is om wat voor type het gaat. Om 1 of andere reden ziet hij dus niet dat een lege PersistentGenericBag<T> van type T is.

Heeft iemand ervaring hiermee? Ik begrijp niet goed waarom de boel niet gewoon gebound kan worden.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Word je collectie gelazy-load toevallig?

Misschien dat typeof(T) dan een proxy type oplevert in plaats van het daadwerkelijke type?
En als je PersistentGenericBag<T> vervangend door IList<T> in je entity, gaat het dan wel goed?

Lastig issue in ieder geval :)

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Hoe ziet jouw class er uit ?

Zo:
(vereenvoudigd)
code:
1
2
3
4
public MyClass
{
   public IList<SomeType> MyList = new PersistentGenericBag<SomeType>();
}

of zo:
code:
1
2
3
4
public MyClass
{
   public PersistentGenericBag<SomeType> MyList = new PersistentGenericBag<SomeType>();
}


Zowiezo moet je uw collecties niet definieren als 'NH collection types', maar gebruik je best die .NET Framework interfaces als type. NH trekt er wel zijn plan mee.

[ Voor 22% gewijzigd door whoami op 16-08-2010 11:59 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ik maak geen gebruik van lazy-loading. Ik heb wel de proxyfactory.factory_class in de config ingesteld op Castle. Ik heb LinFu ook getest maar het probleem doet zich bij beide voor. Aangezien ik lazy-loading op false heb gezet lijkt het me sterk dat hij één van deze libraries überhaupt gebruikt.

Ik map gewoon naar de .NET types dus IList<T>. Ik heb hem wel iets anders want ik initialiseer direct een nieuwe List<T>:

code:
1
2
3
4
public MyClass
{
   public IList<SomeType> MyList = new List<SomeType>();
}


Als ik run-time kijk wat voor type het is geworden dan is het een GenericPersistentBag<SomeType> geworden (wat ik ook zou verwachten).

Een nieuwe PersistentGenericBag<T> kan ik niet aanmaken omdat ik op het moment van initialiseren geen sessie heb en hij throwed dan een exception.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Tony L schreef op maandag 16 augustus 2010 @ 12:26:
Ik maak geen gebruik van lazy-loading. Ik heb wel de proxyfactory.factory_class in de config ingesteld op Castle. Ik heb LinFu ook getest maar het probleem doet zich bij beide voor. Aangezien ik lazy-loading op false heb gezet lijkt het me sterk dat hij één van deze libraries überhaupt gebruikt.
Die libraries worden hoogst waarschijnlijk wel gebruikt hoor.
Lazy loading op collecties / associaties is heel iets anders dan lazy loading op class niveau. By default genereert NH een 'proxy' voor je object, zodanig dat het gebruik kan maken van LazyLoading van de entity (heeft niets te maken met lazy loading van collecties).

Kan het niets te maken hebben met een of andere TypeDescriptor ?

[ Voor 4% gewijzigd door whoami op 16-08-2010 15:40 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ahh ok, dat wist ik niet, sorry.

Maar het blijft een raar probleem he? Ik weet bijna zeker dat de DataGridView niet weet wat voor object type er in de PersistentGenericBag<T> zit. Wat ik raar vind is dat dit best een primitief voorbeeld is. Het lijkt me dat andere mensen er toch ook mee moeten zitten?

Zou iemand zo vriendelijk willen zijn om werkend test project te maken met een DataGridView, BindingSource en een object collectie? Ik heb een test-case gemaakt die iets complexer is dan eigenlijk nodig (wist ik niet op voorhand omdat ik sinds gisteren pas op de IsDataBound gestuit ben).

Het iets complexere voorbeeld + database.MDF kan je hier downloaden:
http://home.planet.nl/~ly...mptyCollectionProblem.zip

Ik ga vanavond een simpeler voorbeeld maken om het probleem weer te geven.

Je kan mijn voorbeeld als volgt testen:
1). Selecteer de eerste row in de linker DataGridView (is als het goed is al geselecteerd).
2). Voeg auto's toe aan deze persoon in de rechter DataGridView (en vul ook wat gegevens in).
3). Selecteer de tweede row in de linker DataGridView.
4). Ga weer terug naar de eerste row in de linker DataGridView en alle info die je hebt ingevuld is weg. Het aantal auto's wat je hebt toegevoegd moet wel overeenkomen.
5). Op het moment dat je nu de data invult van de lege auto's dan wordt het allemaal wel goed opgeslagen.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Heeft iemand heel toevallig een idee wat hier fout gaat?

- De officiële developers van NHibernate reageren er niet op. Ik heb er een issue van gemaakt en een mail over gestuurd maar tot nu toe nog geen reactie (3+ weken geleden). Gisteren een comment geplaatst bij de issue en hopelijk reageren ze daar wel op.
- Op het MSDN forum krijg ik geen response.
- Op het NHibernate forum krijg ik geen response.

Het lijkt er op alsof ik in een donkere grot loop te wroeten waar ik niet meer uit kan komen... Elke IList<T> moet toch gewoon gebind kunnen worden aan een BindingSource?

Ik begrijp er helemaal niets meer van :'(

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
Nou ik heb de moeite even genomen om mijn sql te upgraden naar 2008 R2. (volgende keer ff .bak bij posten)
helaas kan ik je bovenstaande probleem niet simuleren, binding lijkt goed te werken allemaal.

[ Voor 9% gewijzigd door bastv op 20-08-2010 22:17 ]


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
bastv schreef op vrijdag 20 augustus 2010 @ 22:16:
Nou ik heb de moeite even genomen om mijn sql te upgraden naar 2008 R2. (volgende keer ff .bak bij posten)
helaas kan ik je bovenstaande probleem niet simuleren, binding lijkt goed te werken allemaal.
Heb je de stappen zoals hierboven ook precies zo doorgelopen? Een collega van me heeft het thuis ook getest en daar werkt het ook niet.

Je kan het op een andere manier ook goed testen.
1). Ga naar de 2e deelnemer
2). Voeg daar auto's toe en klik op de knop rechtsonder in om de textuele output te zien.
3). Als het goed is worden de waardes in ander scherm niet goed weergegeven.

Mocht dit bij jou wel werken dan ben ik erg benieuwd wat het verschil is tussen jouw ontwikkelomgeving en die van mij.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
ok ik heb denk ik gisteravond niet goed gekeken.
is inderdaad een vreemd probleem..

dit werkt dan weer wel...
C#:
1
public virtual IList<PersonCar> Cars { get;  set; }

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        void personsBindingSource_CurrentChanged(object sender, EventArgs e) {
            if (personsBindingSource.Current != null) {
                Person person = personsBindingSource.Current as Person;
                if (person == null) return;

                if (person.Cars.Count != 0)
                {
                    carsBindingSource.DataSource = person.Cars;
                }
                else
                {
                    person.Cars = new List<PersonCar>();
                    carsBindingSource.DataSource = person.Cars;
                }
            }
        }


maar dit is niet echt netjes.... misschien krijg ik vandaag nog een heldere ingeving :)

Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Klopt dat werkt inderdaad alleen krijg je de boel dan nooit meer gepersisted omdat NHibernate ziet dat de oorspronkelijke GenericPersistentBag<T> is vervangen door iets anders (in dit geval een List<T>).

Ik vind het ook een erg raar probleem. Ik heb vandaag een ingeving gehad die ik morgen wil toepassen. Ik ga de gehele GenericPersistentBag in NHibernate refactoren tot dat ik het probleem gevonden heb. Kennelijk is de IList<T> implementatie niet goed anders moet het gewoon zonder problemen gebound kunnen worden. Dit heb ik op MSDN gisteren bevestigd gekregen.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ik heb de GenericPersistentBag<T> vervangen met een uitgeklede versie. Deze versie werkt nog niet 100% omdat ik te weinig van de inner workings van NHibernate af weet. Het inladen van bestaande data werkt daarom nog niet helemaal maar als ik een nieuwe record in de linker grid toevoeg en daarna nieuwe records in de rechter grid dan wordt de data gewoon goed weggeschreven.

Het lijkt dus wel degelijk een NHibernate issue te zijn. Ik vraag me alleen af hoe nuttig het is om een geheel nieuwe implementatie te maken op de GenericPersistentBag<T>... Ik baal echt als een stekker dat dit niet gewoon out-of-the-box werkt. Ik zit er sterk aan te denken om NHibernate te dumpen en naar wat anders te kijken ;(

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
Dan zal ik eerder winforms dumpen voor WPF.
Dit dan icm een IOC container en MVVM framework als MVVM Light,nRoute of Caliburn Micro etc.

nieuwe technieken met ook betere binding mogelijkheden (auto binding, convention over configuration)

heb je trouwens ook de laatste NHibernate al eens geprobeerd? 3.0 apha2 (de alpha is zeer stable)

Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
bastv schreef op zondag 22 augustus 2010 @ 23:13:
Dan zal ik eerder winforms dumpen voor WPF.
Dit dan icm een IOC container en MVVM framework als MVVM Light,nRoute of Caliburn Micro etc.

nieuwe technieken met ook betere binding mogelijkheden (auto binding, convention over configuration)

heb je trouwens ook de laatste NHibernate al eens geprobeerd? 3.0 apha2 (de alpha is zeer stable)
Alpha 3.0 heb ik getest maar die werkt ook niet.

Ik kan WPF wel helemaal gaan leren maar het project waar ik mee bezig ben kan ik niet zomaar even om zetten. Er zit denk ik al voor zo'n 300+ uur in. Dan kan ik beter de kortste weg kiezen en een andere ORM zoeken.

Uiteindelijk wil ik wel naar WPF en MVVM frameworks maar dat zit er met dit project even niet in.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • farmertjes
  • Registratie: Maart 2010
  • Laatst online: 02-06 20:29
Mocht je geinteresseerd zijn in een alternatief: ben laatst zelf overgestapt van nHibernate naar EntityFramework (vanwege nieuwe werkgever) en moet zeggen dat het me prima bevalt!

[ Voor 32% gewijzigd door farmertjes op 31-08-2010 15:50 ]

flickr


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
Die stap heb ik ook geprobeerd te maken (EF CTP Code-First) maar na een aantal weken weer terug naar NHibernate. Het werkt redelijk maar met nog lang niet zo volwassen als NHibernate.
Over 1,5/2 jaar zal EF wel op het niveau komen van NHibernate denk ik.

Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Dank allemaal!

Kleine update:
Ik heb het EINDELIJK voor elkaar!! :o

In plaats van een IList<T> te binden maak ik nu gebruik van een BindingList<T> en dit werkt wel *O*
Op één of andere manier zorgt de BindingList wel voor een goede databound en een IList<T> niet.

Ik zit nu weer met een andere NHibernate issue maar daar maak ik wel een nieuw topic voor ;)

PSN: Norfirin

Pagina: 1