È un gestore di eventi PropertyChanged errato se viene utilizzato per l'aggiornamento del database?

2

Ho una classe con diversi campi.

public          bool         Active       { get; set; }
public          List<Group>  Groups       { get; set; }
public          string       FirstName    { get; set; }
public          string       LastName     { get; set; }
public          Gender       Gender       { get; set; }
public          string       IdCard       { get; set; }
public          List<string> PhoneNumbers { get; set; }
public          string       Address      { get; set; }
public          string       PicturePath  { get; set; }
public          string       Comments     { get; set; }

Nel database, ho una tabella con i campi corrispondenti. Voglio che ogni volta che cambio il valore di questi campi, il campo corrispondente nella tabella verrà aggiornato automaticamente al nuovo valore.

Ho pensato forse di implementare un evento PropertyChanged , e per quello, ho bisogno di richiamare il gestore di eventi da set . Il problema è che ho letto che i getter di proprietà dovrebbero essere veloce e idempotente :

Though it's perfectly fine to iterate over an in-memory collection of objects, I wouldn't recommend doing any kind of heavy lifting in either get or set parts. Anton Gogolev

Ma il database non aggiorna un "sollevamento pesante"? La mia soluzione è cattiva? Quale altra soluzione suggeriresti?

    
posta Sipo 27.05.2016 - 12:01
fonte

1 risposta

4

Ci sono alcune ragioni contro questo approccio.

  • Astrazioni di perdita. L'aggiornamento di un database non è una cosa priva di rischi. Le cose brutte accadono: la connessione di rete può essere eliminata mentre stai inviando la query di aggiornamento; Il server DNS può essere inattivo; il server del database può uscire dallo spazio. Quando si chiama un metodo come DAL.ProductRepository.Update(Product) , il chiamante si aspetta il rischio di chiamare il metodo, e si aspetta, a sua volta, di rilevare eccezioni o gestire casi eccezionali in qualsiasi altro modo. D'altra parte, quando si esegue currentProduct.Price = 123; , sembra naturale non aspettarsi che venga generata un'eccezione SQL, né il thread principale da bloccare per 30 secondi prima che la connessione scada. Facendo roba di database pesante in un setter, è facile per il chiamante dimenticare i rischi, che non è una buona idea.

  • Le proprietà - sarebbero getter o setter - dovrebbero essere veloci e, per veloce, intendo "le cose che accadono dietro un getter o un setter rimangono relativamente basilari, sia in termini di codice che in termini dell'informatica. "Il motivo è che i chiamanti si aspettano di essere veloci e non aspettarsi troppo lavoro sotto il cofano (anche qui, un tempo di attesa di 30 secondi prima che la connessione scada un buon esempio).

  • Questo approccio è semplicemente raro e viola il Principio di minima sorpresa . L'approccio comune è quello di utilizzare qualsiasi getter e setter e solo quando vengono apportate tutte le modifiche necessarie all'oggetto, passare questo oggetto a qualche repository , un oggetto proprietario del contesto del database.

  • In continuità con il punto precedente, se l'oggetto può aggiornare il database stesso, significa che l'oggetto ha un contesto di database o conosce la stringa di connessione ed è in grado di creare il contesto da quello. L'approccio potrebbe essere problematico, e non è chiaro in quale livello vuoi inserire tale classe.

Tuttavia:

  • Potresti avere un'esigenza molto specifica quando l'aggiornamento del database tramite PropertyChanged ha effettivamente senso. Potrei immaginare, ad esempio, un oggetto di configurazione dell'applicazione che si sincronizza con il database. La sua natura è diversa dagli oggetti Product -style, il che rende irrilevante il Principio di Least Surprise. Se la documentazione di classe è ottima e la cultura del tuo team assicura che la documentazione sia sia letta, l'astrazione rimane perdente, ma i chiamanti saranno a conoscenza delle perdite prima che si verifichino effettivamente. Ancora una volta, tali casi sarebbero rari (e non ne ho ancora visti), ma rimangono validi.
risposta data 27.05.2016 - 13:40
fonte

Leggi altre domande sui tag