11.097 messaggi dal 09 febbraio 2002
Contributi
Ripeto: se puoi fornirmi un progetto minimale senza database posso provare ad aiutarti.
Modificato da BrightSoul il 13 novembre 2018 21.34 -

Enjoy learning and just keep making
213 messaggi dal 03 ottobre 2006
Dovrei essere riuscito a creare un progetto minimale che evidenzia lo stesso errore
ovvero
DataBinding: 'System.Collections.Generic.List`1[[Barca, Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' non contiene una proprietà con nome 'Base'.

L'ho salvato qui
https://1drv.ms/u/s!AlFx5ahF0lldh3BhBeQ8zQG5fijo

Grazie
11.097 messaggi dal 09 febbraio 2002
Contributi
Perfetto, sono riuscito a vedere il problema.

Come ti dicevo, la proprietà "barche" è una collezione e per questo non possiede la proprietà "Base". Quindi non puoi fare Eval("barche.Base"). Te ne puoi rendere conto usando la sintassi <%# Item.barche.Base %>. Infatti... perché usare Eval quando puoi usare Item, che ti permette di arrivare alle proprietà in maniera fortemente tipizzata?

Quindi, dato che "barche" è una collezione, la possiamo dare in pasto a un databound control come una GridView annidata, oppure una ListView oppure un Repeater (dipende da cosa devi fare). Io in questo esempio uso una GridView ma se devi giusto visualizzare tutti i valori delle proprietà "Base" delle barche, basterebbe un Repeater.
Questo è l'ItemTemplate del tuo TemplateField.

<ItemTemplate>
                <asp:GridView runat="server" DataSource='<%# Item.barche %>' ItemType="Barca" AutoGenerateColumns="false" ShowHeader="false">
                    <Columns>
                       <asp:TemplateField>
                           <ItemTemplate><%# Item.Base %></ItemTemplate>
                       </asp:TemplateField>
                    </Columns>
                </asp:GridView>
            </ItemTemplate>


Vedi? Ho usato la proprietà Item.barche come DataSource del GridView annidato. Poi, in questo GridView posso creare una colonna di tipo TemplateField e in esso visualizzerò il valore di Item.Base.

A questo punto funziona.

ciao,
Moreno

Enjoy learning and just keep making
213 messaggi dal 03 ottobre 2006
Grazie mille !!!
quasi tutto chiaro... perchè mi resta un dubbio.
Sono obbligato a mettere due gridview innestate per ottenere questo obiettivo ? O comunque due oggetti innestati?

Se io volessi vedere solo le colonne di barche cioè tutte le colonne della collection navigation property in una sola gridview quale Datasource dovrei impostare?

Usando ObjectDataSource facevo una semplice inner join fra le due tabelle e poi nel datareader ci mettevo le colonne che volevo da entrambe le tabelle che poi andavano a formare una sola gridview...
Non si può più fare?

Se portassi fuori la chiave idevento della tabella evento e la uso come chiave esterna nell'entità barche potrei poi interrogare direttamente l'entità barca ma mi sembra assurdo dover arrivare a ciò perchè la gestione della relazione molti a molti me la sta facendo il framework quindi ci deve essere un altro modo per elencare quali barche fanno parte di quell'idevento.
11.097 messaggi dal 09 febbraio 2002
Contributi
Se il DataSource è una collezione che ha innestata al suo interno un'altra collezione (barche dentro eventi), allora sarà necessario innestare un secondo GridView all'interno del primo. Infatti, per presentare collezioni ti serve necessariamente un databound control come la GridView.


Se io volessi vedere solo le colonne di barche cioè tutte le colonne della collection navigation property in una sola gridview quale Datasource dovrei impostare?

Ok, se vuoi "appiattire" il grafo di oggetti puoi fare un DTO che contenga sia le proprietà dell'evento che quelle della barca. Ad esempio:
public class BarcaEventoDTO
    {
        public int IdEvento { get; set; }
        public int IdBarca { get; set; }
        public string Base { get; set; }
    }

Come vedi, qui non ci sono collezioni innestate, per cui non sarà necessario un altro GridView innestato.
Per ottenere questi DTO, puoi fare come segue:
public IEnumerable<BarcaEventoDTO> GetBarchexEventoDTO()
        {
            IEnumerable<BarcaEventoDTO> query = 
                from Evento ev in eventi where ev.Id==1
                from Barca barca in ev.Barche
                select new BarcaEventoDTO
            {
                IdEvento = ev.Id,
                IdBarca = barca.BarcaID,
                Base = barca.Base
            };

            return query.ToList();
        }


E lato markup finalmente puoi presentare le proprietà IdEvento, IdBarca e Base senza ricorrere a un GridView innestato.
     <asp:GridView ID="BarcheList" runat="server" AllowPaging="false" AllowSorting="true" EnableViewState="true"
        PageSize="10" ItemType="BarcaEventoDTO" SelectMethod="GetBarchexEventoDTO"
        AutoGenerateColumns="False">   
        <Columns>
        <asp:BoundField DataField="IdEvento" />
        <asp:BoundField DataField="IdBarca" />
        <asp:BoundField DataField="Base" />
        </Columns>
    </asp:GridView>


ciao,
Moreno

Enjoy learning and just keep making
213 messaggi dal 03 ottobre 2006
grazie mille per l'aiuto
ora è tutto chiaro e funzionante, sto cominciando a capire... :-)

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.