Frage

Ein Teil der Webanwendung, an der ich arbeite, ist ein Bereich, in dem Nachrichten vom Management an 1...n Benutzer angezeigt werden.Ich habe ein DataAccess-Projekt, das die LINQ to SQL-Klassen enthält, und ein Website-Projekt, das die Benutzeroberfläche darstellt.Meine Datenbank sieht so aus:

Benutzer -> MessageDetail <- Message <- MessageCategory

MessageDetail ist eine Join-Tabelle, die auch ein IsRead-Flag enthält.

Die Liste der Nachrichten ist nach Kategorien gruppiert.Ich habe zwei verschachtelte ListView-Steuerelemente auf der Seite – eines gibt den Gruppennamen aus, während ein zweites darin verschachtelt ist, das an MessageDetails gebunden ist und die Nachrichten selbst ausgibt.Im CodeBehind für die Seite mit den Nachrichten habe ich den folgenden Code:

protected void MessageListDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    var db = new DataContext();

    // parse the input strings from the web form
    int categoryIDFilter;
    DateTime dateFilter;
    string catFilterString = MessagesCategoryFilter.SelectedValue;
    string dateFilterString = MessagesDateFilter.SelectedValue;
    // TryParse will return default values if parsing is unsuccessful (i.e. if "all" is selected"):
    // DateTime.MinValue for dates, 0 for int
    DateTime.TryParse(dateFilterString, out dateFilter);
    Int32.TryParse(catFilterString, out categoryIDFilter);
    bool showRead = MessagesReadFilter.Checked;

    var messages =
        from detail in db.MessageDetails
        where detail.UserID == (int)Session["UserID"]
        where detail.Message.IsPublished
        where detail.Message.MessageCategoryID == categoryIDFilter || (categoryIDFilter == 0)
        where dateFilter == detail.Message.PublishDate.Value.Date || (dateFilter == DateTime.MinValue)
        // is unread, showRead filter is on, or message was marked read today
        where detail.IsRead == false || showRead || detail.ReadDate.Value.Date == DateTime.Today
        orderby detail.Message.PublishDate descending
        group detail by detail.Message.MessageCategory into categories
        orderby categories.Key.Name
        select new
        {
            MessageCategory = categories.Key,
            MessageDetails = categories.Select(d => d)
        };

    e.Result = messages;
}

Dieser Code funktioniert, aber eine große LINQ-Anweisung wie diese in den Code-Behind für ein LinqDataSource-Steuerelement zu stecken, gefällt mir einfach nicht.

Es scheint, als würde ich immer noch Abfragen in die Benutzeroberfläche programmieren, nur dass es jetzt LINQ statt SQL ist.Allerdings bin ich der Meinung, dass der Aufbau einer weiteren Ebene zwischen den L2S-Klassen und der Benutzeroberfläche die Flexibilität von LINQ etwas einschränken würde.Ist es nicht der springende Punkt, die Menge an Code zu reduzieren, die Sie zum Abrufen von Daten schreiben?

Gibt es einen möglichen Mittelweg, den ich nicht sehe, oder verstehe ich einfach falsch, wie LINQ to SQL verwendet werden soll?Für Ratschläge wäre ich sehr dankbar.

War es hilfreich?

Lösung

Alle Ihre LINQ-Abfragen sollten in einem sein Business-Logik-Klasse, keine Änderung gegenüber älteren Methoden wie ADO.

Wenn du eine ... bist Purist Sie sollten immer List(of T) von Ihren Methoden in der Business-Klasse zurückgeben, tatsächlich sollte der Datenkontext nur für die Business-Klassen sichtbar sein.Anschließend können Sie die Liste in der Benutzeroberfläche bearbeiten.

Wenn du eine ... bist Pragmatiker, können Sie ein IQueryable-Objekt zurückgeben und einige Manipulationen an der Benutzeroberfläche vornehmen.

Andere Tipps

Unabhängig von LINQ halte ich es für keine gute Idee, Präsentationscode mit datenbankbezogenem Code zu mischen.Ich würde eine einfache DB-Abstraktionsschicht über LINQ-Abfragen erstellen.Meiner Meinung nach ist LINQ einfach ein praktisches Tool, das keine gravierenden Auswirkungen auf das traditionelle Anwendungsdesign hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top