Tutte le mie funzioni DAL utilizzano dbContext.Database.SqlQuery
per mappare i risultati delle stored procedure negli oggetti di business logic.
La mia applicazione è diventata più complicata e sto cercando un modo moderno e "aggiornato" per gestire le seguenti situazioni. So che posso ottenere ciò usando il componente ADO.NET di basso livello come SqlDataReader
e mappare il risultato manualmente, ma sono sicuro che c'è il modo migliore per farlo utilizzando Entity Framework 6.
Alla domanda: con questo comando dbContext.Database.SqlQuery<MyClass>
, non riesco a gestire:
La stored procedure che restituisce 2 set di risultati
Mappatura del set di risultati su un tipo di dati complesso
Esempio:
public class Order
{
public Customer customer { get; set; }
public Items[] items { get; set; }
}
Ancora una volta, so che posso mapparlo manualmente o con AutoMapper, ma sto cercando un approccio "aggiornato" basato su Entity Framework 6.
Sì, c'è un modo usando Translate .
Adattato dalla documentazione ufficiale :
var cmd = dbContext.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[GetAllCustomersAndOrders]";
dbContext.Database.Connection.Open();
// Run the sproc
var reader = cmd.ExecuteReader();
var Customers= ((IObjectContextAdapter)dbContext)
.ObjectContext
.Translate<Customer>(reader, "Customers", MergeOption.AppendOnly);
reader.NextResult();
var Orders = ((IObjectContextAdapter)db)
.ObjectContext
.Translate<Order>(reader, "Orders", MergeOption.AppendOnly);
Per quanto riguarda il problema della mappatura
poche colonne dal risultato a un tipo complesso di 2 ° livello? ad esempio: SELECT FirstName, LastName, OrderId FROM Orders Desidero associarlo a: public class Order {pubblico Cliente cliente {get; impostato; } public int OrderId {get; impostato; }}
La cosa migliore sarebbe utilizzare un CustomerId all'interno della tabella degli ordini , facendo riferimento a una tabella Customer , invece di FirstName / LastName . Sarebbe un buon refactoring, normalizzando il database. Altrimenti non avrai una vera mappatura tra i tuoi oggetti e il tuo database, poiché il tuo oggetto Ordine avrà una proprietà Customer che non esiste nel tuo database. In tal caso, dovrai creare una classe, ad es. NormalizedOrder
public class NormalizedOrder {
int OrderId { get; set; };
Customer OrderCustomer { get; set; };
}
E poi, dopo il codice sopra dove recuperi tutti gli ordini, fai qualcosa di simile
var NormalizedOrders = Orders.Select new Order(){OrderId = e.OrderId, OrderCustomer = new Customer(){FirstName=>e.FirstName,LastName=>e.LastName}};