Sto sviluppando un'API web .NET Core che utilizza .NET Core 2.0 e Entity Framework 2.0. Il progetto e in particolare la quantità di modelli di visualizzazione continuano a crescere e la complessità diventa più intensa (modelli più nidificati). Il punto principale per la mia domanda è che i modelli di visualizzazione condividono molti sottomodelli.
E scommetto che non uso le parole chiave corrette per googling perché non riesco a trovare quello che voglio sapere.
Attualmente interrogato e mappato (secondo alcune logiche definite) direttamente tramite DbContext (ogni volta aka per ogni modello di vista). Per esempio:
List<MyViewModel1> items = await MyDbContext.MyDbModel1
.Where(dbm1 => dbm1.SomeValue > 10)
.Select
(
dbm1 => new MyViewModel1
{
ValueName = dbm1.SomeValue,
NestedModel1 = new NestedViewModel1
{
SomeValue1 = dbm1.OtherTableModel1.Value1,
SomeValue2 = dbm1.OtherTableModel1.Value2
},
NestedModel2 = (!dbm1.OtherTableModel2Id.HasValue) ? null :
new NestedViewModel2
{
SomeCalculatedValue = dbm1.OtherTableModel2.Value1 + dbm1.OtherTableModel2.Value2,
SomeOtherValue = dbm1.OtherTableModel2.Value3
}
}
)
.ToListAsync();
Ora il problema è: NestedViewModel2 (quello con il calcolo) è collegato a più modelli di visualizzazione e finora scrivo questo calcolo ogni volta nello stesso modo di sopra (per MyViewModel1, MyViewModel2, MyViewModel3, ...). E così com'è, i requisiti cambiano regolarmente. E ogni volta che cambiano i requisiti, devo individuare tutti i punti del mio codice in crescita e correggere il calcolo su più punti.
Questo approccio non segue DRY (non ripetersi).
Ma non riesco a trovare informazioni se è possibile (e come) scrivere alcuni metodi di estensione linq personalizzati (che il framework di entità comprenderà per la conversione da linq a SQL) come:
e specialmente i modelli annidati selezionano in un posto (che può essere chiamato dai metodi sopra).
Qualche suggerimento per me su come impacchettare queste query nei metodi di estensione di linq personalizzati in modo che il codice segua il principio di DRY e possa essere riutilizzato?
Si dovrebbe dare un'occhiata a un framework di mappatura per mappare le Entità DB su ViewModels. Ad esempio, stiamo usando Automapper per raggiungere questo obiettivo.
Ciò consente di definire centralmente i mapping e riutilizzarli. Questo dovrebbe semplificare la maggior parte del codice, perché la logica che si desidera refactoring è nella parte select
della query.
MappingConfig.CreateMap<MyDbModel1, MyViewModel1>()
.ForMember(vm => vm.ValueName, o => o.MapFrom(ent => ent.SomeValue))
.ForMember(vm => vm.NestedModel1, o => o.MapFrom(ent => ent.OtherTableModel1));
MappingConfig.CreateMap<OtherTableModel1, NestedViewModel1>()
.ForMember(vm => vm.SomeValue1 , o => o.MapFrom(ent => ent.Value1))
.ForMember(vm => vm.SomeValue2 , o => o.MapFrom(ent => ent.Value2));
var items = Mapper.Map<MyViewModel1[]>(MyDbContext.MyDbModel1.Where(dbm1 => dbm1.SomeValue > 10));