2016-01-07 17 views
9

ho il seguente codice:Linq selezionare tornare stringa invece dell'oggetto

var languages = _languageService 
      .GetAll() 
      .Select(x => (((LanguageViewModel) new LanguageViewModel().InjectFrom(x)))) 
      .ToList(); 

Durante l'esecuzione di questo, languages diventa, come previsto, una raccolta di LanguageViewModel oggetti:

Working

Quello che ho Sto cercando di fare è, quando si seleziona, anche convertire la proprietà Code dell'oggetto in maiuscolo, in questo modo:

var languages = _languageService 
      .GetAll() 
      .Select(x => (((LanguageViewModel) new LanguageViewModel().InjectFrom(x)).Code = x.Code.ToUpper())) 
      .ToList(); 

Mi aspetto l'oggetto languages di avere più LanguageViewModel s in essa, ma sembra che questo:

enter image description here

La mia ipotesi è il fatto che sto usando una dichiarazione come Select(x => (new Object().Property = Value)) seleziona il Property. Ma poi, come posso restituire un oggetto con una delle sue proprietà modificate? L'uso dell'inizializzatore di oggetti prima dell'iniezione non è un'opzione in quanto viene sovrascritto, usandolo dopo l'Inject non è possibile, in quanto non è ancora stato lanciato, così ho ottenuto qui la soluzione che non sembra funzionare. Qualche consiglio molto apprezzato.

+0

Stai selezionando solo il codice. Prendi in considerazione l'utilizzo di un metodo di supporto per mappare/formattare il tuo oggetto. – ryanyuyu

+1

Stai già mappando 'LanguageViewModel' dall'entità' Language' usando il metodo 'InjectFrom()'. Perché non 'this.Code = languge.Code.ToUpper()' invece nel metodo di mappatura? Questo è il punto centrale di un modello di visualizzazione - che si adatta alle esigenze specifiche della vista ... – haim770

+1

InjectFrom() è una funzione di Omu.ValueInjecter, un pacchetto NuGet specializzato in injecting di valore. Sarebbe una buona idea cambiarlo? Ne dubito .. –

risposta

8

Hai indovinato ciò che è sbagliato: hai cambiato il tuo corpo lambda in un'espressione che restituisce una stringa.

Non è possibile scrivere il corpo lambda come una singola espressione che fa ciò che si desidera, ma non è necessario. È possibile inserire più istruzioni in un lambda:

var languages = _languageService 
    .GetAll() 
    .Select(x => { 
     var lvm = (LanguageViewModel)new LanguageViewModel().InjectFrom(x); 
     lvm.Code = x.Code.ToUpper(); 
     return lvm; 
    }) 
    .ToList(); 

Mi piacerebbe un modo per farlo con meno digitando. Sarebbe piuttosto fresco se la notazione di proprietà di impostazione per i costruttori sono stati generalizzato a "impostare le proprietà su un valore di ritorno":

var foo = new Bar() { Armpit = new Flapdoodle() { Limpet = 2 } }; 
var baz = foo.Armpit { Limpet = 4 }; 

Sì, scommetto il C# team'll mollare tutto e ottenere il diritto su di essa. ..

non so se l'esplicito LanguageViewModel cast è effettivamente necessario o no, ma è avuto così l'ho lasciato in.

+1

Se stai usando il cast sicuro, dovresti anche controllare se 'lvm' non è nullo prima di andare oltre. Dico solo ... – Atlasmaybe

+0

@Atlasmaybe Buon punto. L'ho cambiato con lo stesso cast non sicuro che aveva originariamente. Molte persone sentono "semplicemente dicendo" come leggermente antipatico. Justin '... (/ s) –

+0

+1 Ma, supponendo che 'InjectFrom' restituisca un tipo più astratto (meno specifico) di' LanguageViewModel', non penso '(LanguageViewModel) new LanguageViewModel(). InjectFrom (x); 'eseguirà anche la compilazione ... – haim770

1

la vostra linea Select potrebbe essere riscritto per

.Select(x => 
{ 
    var vm = new LanguageViewModel().InjectFrom(x); 
    vm.Code = vm.Code.ToUpper(); 
    return vm; 
})