Una soluzione semplice è quella di usare LINQ, ovvero esponi una proprietà IEnumerable<People> e dentro fail'ordinamento secondo la proprietà BirthDate, essendo la orderby un deferred operator, ogni volta che il chiamante scorre la lista viene riordinata.
Altra opssibilità, le entità implementano la INotifyPropertyChanged (e qui si può aprire un mondo di discussione), quindi quando aggiungi una person al gruppo, lui si registra per la PropertyChanged e monitora quando la proprietà BirthDay Cambia.
Alternativamente, se la relazione è bidirezionale, ovvero Person ha un link ai gruppi a cui appartiene, potrebbe esser nel setter di BirthDate che Person comunica a tutti i gruppi che la proprietà è cambiata.
Alk.
--Blog Eng: http://www.codewrecks.com/blogBlog Ita: http://blogs.ugidotnet.org/rgmTwitter: http://twitter.com/alkampfer
petrux:> Una soluzione semplice è quella di usare LINQ, ovvero esponi una > proprietà IEnumerable e dentro fail'ordinamento secondo la > proprietà BirthDate, essendo la orderby un deferred operator, ogni volta > che il chiamante scorre la lista viene riordinata. cosa intendi per "dentro"?
Internamente alla prooprietà, se tu fai una propreità di tipo IEnumerable<Oggetto> nella get restituisce un _innerlist.Orderby(o => o.proprietà)
Per l'inotifypropertychanged alla fine è un observer pattern :)
Ciao alk,
Gian Maria Ricci: Internamente alla prooprietà, se tu fai una propreità di tipo IEnumerable<Oggetto> nella get restituisce un _innerlist.Orderby(o => o.proprietà)
...mumble mumble... Ok, facciamo il merge con l'altro thread (quello del mapping di una lista). Il mio scenario è questo (codice non testato, lo sto scrivendo al volo :-p):
class Person { DateTime BirthDay { get; set; } }
class Group {
private bool wrapList = true;
private IList<Person> people; //per il mapping
public IEnumerable<Person>
{
get {
if (wrapList) people = new PersonContainer(people);
return people;
}
internal class PersonContainer : IList<Person>
internal PersonContainer(IEnumerable<Person> range) { ... }
//blablabla
Dentro la classe PersonContainer poi eseguo l'ordinamento che viene ri-eseguito ad ogni GetEnumerable() se nella lista è occorso un cambiamento. La domanda che mi preme è: ma poi NHibernate tiene traccia dell'*istanza* che lui ha mappato sulla propety "people", oppure all'update prende quello che trova e lo riscrive sul db?
Gian Maria Ricci: Per l'inotifypropertychanged alla fine è un observer pattern :)
Uhm... come pure l'evento che notifica il cambiamento di una data property. Quello che mi chiedo: è "ortodosso" che a consumare l'evento sia un altra entità del modello?
Ciao,
petrux
Io farei una cosa più semplice tipo questa
public IEnumerable<Person> PErsons
return people.OrderBy(p => p.BirthDay);
Ovvero usi link per tornare un ienumeable ordinato della lista originale. Dato che linq ti restituisce un deferred operator, praticamente ogni volta che il chiamante enumera la lista essa viene riordinata, per cui non hai problemi. In questo caso nhibernate salva nel DB la lista interna people in maniera non ordinata, perchè è il domain model che la ordina per il chiamante senza problemi.
Il fatto che sia Ortodosso o meno che un'entità consumi un evento di change se ne potrebbe discutere molto, ma grazie a linq, se qualcuno cambia un proprietà birthday di un oggetto nella lista, quando rilegge la proprietà gli oggetti li trova sempre ordinati :) è per questo che probabilmente è la soluzione più semplice.
Gian Maria Ricci: Io farei una cosa più semplice tipo questa public IEnumerable<Person> PErsons { get { return people.OrderBy(p => p.BirthDay); { } Ovvero usi link per tornare un ienumeable ordinato della lista originale. Dato che linq ti restituisce un deferred operator, praticamente ogni volta che il chiamante enumera la lista essa viene riordinata, per cui non hai problemi. In questo caso nhibernate salva nel DB la lista interna people in maniera non ordinata, perchè è il domain model che la ordina per il chiamante senza problemi. Il fatto che sia Ortodosso o meno che un'entità consumi un evento di change se ne potrebbe discutere molto, ma grazie a linq, se qualcuno cambia un proprietà birthday di un oggetto nella lista, quando rilegge la proprietà gli oggetti li trova sempre ordinati :) è per questo che probabilmente è la soluzione più semplice.
Ok, tutto molto più chiaro. L'unica cosa è che la persistenza vedrà un ordine diverso da quello "reale". Ora rimane solo da verificare se l'istanza della IList che NHibernate inietta nel mio oggetto di dominio viene tracciata o ri-letta in fase di update.
Gian Maria Ricci: Io farei una cosa più semplice tipo questa public IEnumerable<Person> PErsons { get { return people.OrderBy(p => p.BirthDay); { }
ho notato questo:
public class Foo
public int Seed { get; set; }
public string Label { get; set; }
public class FooContainer
protected IList<Foo> fooList = new List<Foo>();
public IEnumerable<Foo> FooList
get { return fooList.OrderBy((f) => f.Seed); }
public void Add(Foo foo)
fooList.Add(foo);
public bool Remove(Foo foo)
return fooList.Remove(foo);
class Program
static void Main(string[] args)
try
FooContainer c = new FooContainer();
c.Add(new Foo() { Label = "1", Seed = 1 });
c.Add(new Foo() { Label = "2", Seed = 2 });
c.Add(new Foo() { Label = "3", Seed = 3 });
c.Add(new Foo() { Label = "4", Seed = 4 });
c.Add(new Foo() { Label = "5", Seed = 5 });
foreach (Foo f in c.FooList)
if (f.Seed == 3)
c.Add(new Foo() { Label = "IMPOSSIBILE", Seed = -1 });
catch (Exception e)
Console.WriteLine(e.Message);
se qualcuno sta enumerando una collection e questa nel frattempo viene modificata, in teoria continuando l'iterazione si dovrebbe avere una eccezione che in questo caso *non si ha* visto che l'IEnumerable<Foo> su sui sto enumerando non è la collection che vado a visitare. Non è un po' misleading?
--
Chiaramente la semantica dell'ienumerable in questo caso è cambiata. Direi che non è un problema insormontabile, raramente capita di dovere enumerare e contemporaneamente aver una buona ragione per cambiare la lista.
Chiaramente se questa difformità dal funzionamento base non è accettabile allora ti puoi fare una tua implementazione di una lista che internamente si ordina e lancia eccezione se qualcuno la modifica durante l'enumerazione. ;)
alk.