2 Stimmen

Verbundenen Wert für gebundenes Feld ohne benutzerdefinierten Typ anzeigen?

Ich habe eine GridView, die an eine ICollection<UserAnswer> die zwei Spalten anzeigen muss:

<asp:GridView ID="UserAnswersGridView" runat="server">
    <Columns>
         <asp:BoundField DataField="Question.Name" HeaderText="Question Name" SortExpression="QuestionID" />
         <asp:BoundField DataField="Score" HeaderText="Score" SortExpression="Score" />
    </Columns>
</asp:GridView>

Aber ich erhalte die Fehlermeldung:

Ein Feld oder eine Eigenschaft mit dem Namen 'Question.Name' wurde in der ausgewählten Datenquelle nicht gefunden.

Jede UserAnswer hat eine QuestionId Wert, den ich zur Abfrage des Fragennamens verwenden würde. Im Code würde ich einfach aufrufen userAssessment.Question.Name aber wie würde ich dies mit einer gebundenen Spalte in einem GridView tun, ohne einen neuen Typ zu erstellen?

Als Referenz ist dies die Methode, die die Daten zurückgibt:

public static ICollection<UserAnswer> GetUserAnswers(Int32 userAssessmentId)
{
    DataContext database = new DataContext(GetConnectionString());
    return database.UserAnswers.Where(u => u.UserAssessmentId == userAssessmentId).ToList();
}

Tut mir leid, wenn diese Erklärung nicht sehr klar ist!

2voto

Marc Gravell Punkte 970173

Creo que GridView unterstützt nur Eigenschaften des unmittelbaren Typs. Ist Repeater oder etwas Ähnliches eine Option? Das gibt Ihnen mehr Flexibilität.

Alternativ dazu können Sie dem Typ über eine partielle Klasse Shim-Eigenschaften hinzufügen:

namespace YourLinqNamespace {
    partial class UserAnswer {
        public string QuestionName {get {return Question.Name;}}
    }
}

Sie können dies nicht in Filtern verwenden ( Where usw.), aber Sie sollten in der Lage sein, es für zurückgegebene Objekte ohne Probleme zu verwenden. Beachten Sie, dass Sie möglicherweise LoadWith um die Hin- und Rückflüge zu sparen:

DataLoadOptions options = new DataLoadOptions();
options.LoadWith<UserAnswer>(x=>x.Question);
database.LoadOptions = options;

1voto

JoshBerke Punkte 64214

Sie könnten auch das ItemDataBoundEvent verwenden, um das Feld im Code dahinter zu setzen. Oder Sie könnten einen anonymen Typ verwenden, der dem Konzept von Marcs Shim-Eigenschaft ähnelt, aber Sie würden Ihr Domänenmodell nicht ändern.

 from u in database.UserAnswers
 Where u.UserAssessmentId == userAssessmentId
 select new { QuestionName=u.Question.Name,
              Answer = u.Answer
              //etc etc
            };

Wie Marc darauf hingewiesen, sollten Sie nicht einen anonymen Typ von einer Methode zurückgeben, habe ich Trick verwendet, wenn manuell Bindung an die Datenquelle so:

myGrid.DataSource= von u etc....

Meiner Meinung nach ist es besser, meinen ersten Vorschlag zu verwenden und ihn im Ereignis "Elementdaten gebunden" zu behandeln.

1voto

DavGarcia Punkte 18140

Wie Marc Gravell erstelle ich für diese Fälle fast immer Ausgleichseigenschaften. Eine andere Möglichkeit wäre die Verwendung einer Vorlagenspalte anstelle einer gebundenen Spalte, aber das hängt wirklich von Ihrer Situation ab:

<asp:TemplateField HeaderText="Question Name">
  <ItemTemplate>
    <%# Eval("Question.Name") %>
  </ItemTemplate>
</asp:TemplateField>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X