Передовой опыт: LINQ To SQL для доступа к данным - PullRequest
6 голосов
/ 06 сентября 2008

Часть веб-приложения, над которым я работаю, - это область, где отображаются сообщения от руководства для 1 ... n пользователей. У меня есть проект DataAccess, который содержит классы LINQ to SQL, и проект веб-сайта, который является пользовательским интерфейсом. Моя база данных выглядит так:

Пользователь -> MessageDetail <- Сообщение <- MessageCategory </p>

MessageDetail - это таблица соединений, которая также содержит флаг IsRead.

Список сообщений сгруппирован по категориям. У меня есть два вложенных элемента управления ListView на странице: один выводит имя группы, а второй - внутри, который связан с MessageDetails, и выводит сами сообщения. В коде для страницы со списком сообщений у меня есть следующий код:

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;
}

Этот код работает , но придерживаться огромного оператора LINQ, подобного этому, в выделенном для кода элементе управления LinqDataSource просто не подходит мне.

Похоже, я все еще кодирую запросы в пользовательском интерфейсе, только теперь это LINQ вместо SQL. Тем не менее, я чувствую, что построение еще одного слоя между классами L2S и пользовательским интерфейсом уменьшит некоторую гибкость LINQ. Разве нет смысла уменьшать объем кода, который вы пишете для извлечения данных?

Есть ли какая-то возможная золотая середина, которую я не вижу, или я просто неправильно понимаю, как предполагается использовать LINQ to SQL? Совет будет принята с благодарностью.

Ответы [ 2 ]

5 голосов
/ 25 сентября 2008

Все ваши запросы LINQ должны быть в классе бизнес-логики , без изменений от более старых методологий, таких как ADO.

Если вы пурист , вы всегда должны возвращать List (of T) из ваших методов в бизнес-классе, на самом деле, текст данных должен быть виден только бизнес-классам. Затем вы можете манипулировать списком в пользовательском интерфейсе.

Если вы прагматик , вы можете вернуть объект IQueryable и сделать некоторые манипуляции в пользовательском интерфейсе.

1 голос
/ 06 сентября 2008

Независимо от LINQ, я думаю, что смешивать код презентации с кодом, связанным с базой данных, не очень хорошая идея. Я бы создал простой слой абстракции БД поверх запросов LINQ. На мой взгляд, LINQ - это просто удобный инструмент, который не оказывает серьезного влияния на традиционный дизайн приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...