2010-04-25 9 views
5

OK quindi ho una vista "Dettagli" del cliente fortemente tipizzata che accetta un modello di oggetto Cliente.ASP.NET MVC/LINQ: Qual è il modo corretto di ripetere un Linq.EntitySet in una vista?

Sto utilizzando LINQ su SQL e ogni cliente può disporre di più spazi (parcheggio).

Questa è una relazione FK nel database, quindi il modello Cliente generato da LINQ ha una raccolta "Spaces". Grande!

Ecco un frammento di codice dal mio CustomerRepository dove ho scorrere posti auto del Cliente per eliminare tutti i pagamenti, gli spazi e poi finalmente il cliente:

public void Delete(Customer customer) 
{ 
    foreach (Space s in customer.Spaces) 
     db.Payments.DeleteAllOnSubmit(s.Payments); 
    db.Spaces.DeleteAllOnSubmit(customer.Spaces); 
    db.Customers.DeleteOnSubmit(customer); 
} 

tutto funziona come previsto!

Ora nella mia vista "Dettagli" Voglio popolare una tabella con gli spazi del Cliente:

<% foreach (var s in Model.Spaces) 
    { %> 
    <tr> 
     <td><%: s.ID %></td> 
     <td><%: s.InstallDate %></td> 
     <td><%: s.SpaceType %></td> 
     <td><%: s.Meter %></td> 
    </tr> 
<% } %> 

ottengo il seguente errore:

foreach statement cannot operate on variables of type 'System.Data.Linq.EntitySet' because 'System.Data.Linq.EntitySet' does not contain a public definition for 'GetEnumerator'

Infine, se aggiungo questo po 'di codice per la mia classe parziale cliente e utilizzare il foreach nella vista per iterare attraverso ParkingSpaces tutto funziona come previsto:

public IEnumerable<Space> ParkingSpaces 
{ 
    get 
    { 
     return Spaces.AsEnumerable(); 
    } 
} 

Il problema qui è che non voglio ripetermi. Stavo anche pensando che avrei potuto usare un ViewModel per passare una collezione di Spaces alla View, tuttavia LINQ già deduce e crea la proprietà Spaces sul modello del Cliente, quindi penso che sarebbe più pulito usarlo.

Mi manca qualcosa di semplice o mi sto avvicinando in modo errato?

Grazie!

+0

La tua vista è fortemente digitata in 'IEnumerable '? Se non lo è, probabilmente è questo il motivo per cui non puoi enumerarlo, senza quel bit di codice helper. –

+0

La mia vista è fortemente digitata in Inherits = "System.Web.Mvc.ViewPage " Forse non ero abbastanza chiaro, ma la vista fornisce i dettagli dell'account di un cliente. Il cliente ha un numero qualsiasi di spazi che dovrebbero essere visualizzati in questa pagina. Quindi non voglio solo un elenco di spazi, voglio una vista dettagliata di un account cliente compresi gli spazi del cliente. –

risposta

14

Scusate se ritengo che sia un po 'in ritardo, ma il metodo corretto per risolvere il problema è aggiungere un riferimento all'assembly al file web.config in modo che la vista possa accedere al metodo GetEnumerator(). È possibile farlo utilizzando la stringa di riferimento dell'assembly fornita nell'errore di compilazione della pagina. esempio

<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

+0

Questo ha funzionato per me. – Rob

+0

Questo ha funzionato anche per me, sembra stupido che non avvenga di default –

+0

Come cambierebbe questa risposta data un'app web ASP.Net MVC usando il motore di visualizzazione Razor? – beaudetious

1

Ci sono due modi in cui puoi farlo, oltre al tuo piccolo metodo di supporto.

È possibile ereditare un IEnumerable della classe nella pagina:

<%@ Page Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Space>>" %> 

<% foreach (var item in Model) 
    { 

Oppure si può lanciare la vostra oggetto entità a un oggetto IEnumerable:

<% foreach (var item in Model.Spaces as IEnumerable<Space>) 
    { 
+0

Per la prima opzione: come accennato nel mio commento al mio post originale, non sto cercando semplicemente di elencare Spaces, ma di visualizzare informazioni dettagliate sull'account del modello dell'oggetto Cliente in cui il modello dell'oggetto Customer contiene un EntitySet di spazi. Per la seconda opzione: Ho provato a trasmettere nell'istruzione foreach, tuttavia ottengo il seguente errore: "Impossibile convertire implicitamente il tipo 'System.Data.Linq.EntitySet ' a 'object'" - Sto pensando che usare l'approccio View Model è la strada da percorrere, ma non voglio duplicarmi. –

1
  • Prima di tutto che utilizzano visualizzare i modelli anziché accedere direttamente alle DTO è preferibile a . (Uso Automapper per questo)

  • In secondo luogo, fortemente digitare le vostre opinioni al Visualizza modello e nella vista del modello hanno un elenco IEnumerable o passato alla vista , allora si può scorrere attraverso di essa

+0

Come farei per creare il modello di vista senza duplicare la raccolta di spazi? Sto usando il tutorial di NerdDinner come modello e l'esempio di un modello di visualizzazione è una classe che accetta un modello di oggetto Cliente e aggiunge anche proprietà aggiuntive per integrare il modello originale che viene passato. In questo caso, troverei un EntitySet of Spaces e una raccolta IEnumerable separata. Potete indicarmi la direzione di una risorsa che spiegherebbe il modo corretto di strutturare questo modello di vista? Grazie! –

+0

La regola generale è che tutte le informazioni necessarie per la visualizzazione saranno nel modello di vista che si passa, quindi questo modello di visualizzazione è personalizzato e sarà riempito con dati provenienti da DTO o DTO. Nel caso in cui si desideri passare un oggetto IEnumerable, il modello di visualizzazione avrà un oggetto IEnumerable in esso –

1

Basta aggiungere un riferimento a System.Data.Linq al progetto.

Problemi correlati