Linq (Entity Framework) против SQL для динамического подкачки данных - PullRequest
1 голос
/ 11 марта 2012

Я пытался переключиться с SQL TableAdapters на Linq с помощью Entity Framework, однако некоторые элементы мешают мне, и в то же время сводят меня с ума.

У меня есть ASP.NET 4.0 C #Сайт проекта VS2010.

Мои требования следующие:

  • Данные должны быть доступны для вывода на экран
  • Данные должны быть динамически упорядоченными (т. Е. ORDER BY SelectedColumnName ASC / DESC)
  • Данные должны фильтроваться на основе веб-элементов управления, текстовых полей, раскрывающихся списков и т. Д. Опять же, динамически.
  • Возвращаемые столбцы должны быть динамически создаваемыми
  • Работа с большими таблицами должна выполняться следующим образом:отзывчивый, насколько это возможно.Пейджинг помогает в этом.
  • На веб-интерфейсе должна отображаться информация о записи.т. е. «Отображение записи 1-20 из 100», «Страница 5 из 20» и т. д.
    • Проект только для внутреннего доступа.Ни в Интернете, ни в чем-либо другом.

Исходя из своих требований, я начал смотреть на Dynamic Linq, используя пространство имен System.Linq.Dynamic.У меня был некоторый успех, но в основном мои запросы стали слишком сложными.

Для моих требований есть ли реальная причина использовать Linq и Entity Framework по сравнению со стандартным SQL?

Из того, что я могу сказать,Стандартный SQL дает мне все необходимое управление с помощью языка запросов, который я могу понять и контролировать.Linq - это язык, с которым я не очень хорошо знаком, и он не позволяет мне делать все элементы динамически из коробки, как мне нужно.

Не ошибся ли я, вернувшись к использованию хранимых в SQL процедурАдаптеры / table для моих запросов?

Одна вещь, которую я узнал из своих экспериментов с Linq, заключается в том, что управление свойствами с помощью codebehind дает намного лучший контроль над информацией, поэтому я могу использовать эти данные для анализа хранимых процедур для данных.

Это пример выражения Linq, с которым я работал:

private void FetchData()
{
    using (var Context = new ProjectEntities())
    {
        string Fields = GetDynamicFields();

        var Query =
            Context.Users
            .Join(Context.UserStats,            // Table to Join
                u => u.msExchMailboxGuid,       // Column to Join From
                us => us.MailboxGuid,           // Column to Join To
                (u, us) => new                  // Declare Columns for the next Join
                {
                    ObjectGuid = u.objectGuid,
                    msExchMailboxGuid = u.msExchMailboxGuid,
                    CompanyName = u.CompanyName,
                    ResellerOU = u.ResellerOU,
                    DisplayName = u.DisplayName,
                    MBXServer = u.MBXServer,
                    MBXSG = u.MBXSG,
                    MBXDB = u.MBXDB,
                    MBXWarningLimit = u.MBXWarningLimit,
                    MBXSendLimit = u.MBXSendLimit,
                    MBXSendReceiveLimit = u.MBXSendReceiveLimit,
                    extensionAttribute10 = u.extensionAttribute10,
                    legacyExchangeDN = u.legacyExchangeDN,
                    UserPrincipalName = u.UserPrincipalName,
                    Mail = u.Mail,
                    lastLogonTimeStamp = u.lastLogonTimestamp,
                    createTimeStamp = u.createTimeStamp,
                    modifyTimeStamp = u.modifyTimeStamp,
                    altRecipient = u.altRecipient,
                    altRecipientBL = u.altRecipientBL,
                    DeletedDate = u.DeletedDate,
                    MailboxGuid = us.MailboxGuid,
                    Date = us.Date,
                    AssociatedItemCount = us.AssociatedItemCount,
                    DeletedItemCount = us.DeletedItemCount,
                    ItemCount = us.ItemCount,
                    LastLoggedOnUserAccount = us.LastLoggedOnUserAccount,
                    LastLogonTime = us.LastLogonTime,
                    StorageLimitStatus = us.StorageLimitStatus,
                    TotalDeletedItemSize = us.TotalDeletedItemSize,
                    TotalItemSize = us.TotalItemSize,
                    MailboxDatabase = us.MailboxDatabase
                })
            .Join(Context.TechContacts,         // Table to Join
                u => u.UserPrincipalName,       // Column to Join From
                tc => tc.UPN,                   // Column to Join To
                (u, tc) => new                  // Declare Final Column Names
                {
                    ObjectGuid = u.ObjectGuid,
                    msExchMailboxGuid = u.msExchMailboxGuid,
                    CompanyName = u.CompanyName,
                    ResellerOU = u.ResellerOU,
                    DisplayName = u.DisplayName,
                    MBXServer = u.MBXServer,
                    MBXSG = u.MBXSG,
                    MBXDB = u.MBXDB,
                    MBXWarningLimit = u.MBXWarningLimit,
                    MBXSendLimit = u.MBXSendLimit,
                    MBXSendReceiveLimit = u.MBXSendReceiveLimit,
                    extensionAttribute10 = u.extensionAttribute10,
                    legacyExchangeDN = u.legacyExchangeDN,
                    UserPrincipalName = u.UserPrincipalName,
                    Mail = u.Mail,
                    lastLogonTimeStamp = u.lastLogonTimeStamp,
                    createTimeStamp = u.createTimeStamp,
                    modifyTimeStamp = u.modifyTimeStamp,
                    altRecipient = u.altRecipient,
                    altRecipientBL = u.altRecipientBL,
                    DeletedDate = u.DeletedDate,
                    MailboxGuid = u.MailboxGuid,
                    Date = u.Date,
                    AssociatedItemCount = u.AssociatedItemCount,
                    DeletedItemCount = u.DeletedItemCount,
                    ItemCount = u.ItemCount,
                    LastLoggedOnUserAccount = u.LastLoggedOnUserAccount,
                    LastLogonTime = u.LastLogonTime,
                    StorageLimitStatus = u.StorageLimitStatus,
                    TotalDeletedItemSize = u.TotalDeletedItemSize,
                    TotalItemSize = u.TotalItemSize,
                    MailboxDatabase = u.MailboxDatabase,
                    // New Columns from this join
                    UPN = tc.UPN,
                    Customer_TechContact = tc.Customer_TechContact,
                    Customer_TechContactEmail = tc.Customer_TechContactEmail,
                    Reseller_TechContact = tc.Reseller_TechContact,
                    Reseller_TechContactEmail = tc.Reseller_TechContact,
                    Reseller_Name = tc.Reseller_Name
                })
            .Where(u => true)
            .OrderBy(GlobalVars.SortColumn + " " + GlobalVars.SortDirection)
            .Select("New(" + Fields + ")");

        // Add Extra Filters
        if (!(string.IsNullOrWhiteSpace(SearchCompanyNameTextBox.Text)))
        {
            Query = Query.Where("CompanyName.StartsWith(@0)", SearchCompanyNameTextBox.Text);
        }

        // Set the Record Count
        GlobalVars.TotalRecords = Query.Count();

        // Add Paging
        Query = Query
            .Skip(GlobalVars.Skip)
            .Take(GlobalVars.Take);

        // GridView Datasource Binding
        GridViewMailboxes.DataSource = Query;
        GridViewMailboxes.DataBind();
    }
}

Это пример того же с помощью запроса SQL:

DECLARE @SQLSTATEMENT NVARCHAR(4000);
DECLARE @FieldList varchar(MAX);
DECLARE @OrderBy varchar(100);
DECLARE @OrderDirection varchar(100);
DECLARE @PageSize int;
DECLARE @StartRow int;

SET @FieldList = 'u.UserPrincipalName, u.Mail, us.TotalItemsize, tc.UPN';
SET @OrderBy = 'u.CompanyName';
SET @OrderDirection = 'ASC';
SET @PageSize = 20;
SET @StartRow = 80;

SET @SQLSTATEMENT = '
SELECT TOP(@PageSize) * FROM
(
SELECT ' + @FieldList + ' 
,row_number() OVER (ORDER BY @OrderBy ' + @OrderDirection + ') AS [row_number]
FROM Users As u
INNER JOIN UserStats as us
ON u.msExchMailboxGuid = us.MailboxGuid
INNER JOIN TechContacts AS tc
ON tc.UPN = u.UserPrincipalName
) AS r
WHERE r.[row_number] > @StartRow '

EXEC sp_executesql @SQLSTATEMENT,
N'@FieldList varchar(MAX), @OrderBy varchar(100), @OrderDirection varchar(100), @PageSize int, @StartRow int',
@FieldList, @OrderBy, @OrderDirection, @PageSize, @StartRow

Я ценю, что это своего рода открытый вопрос, если бы я мог сделать это более ясным, я бы, конечно, понял.Однако я изо всех сил пытаюсь увидеть преимущества использования Linq в моей ситуации, учитывая мои требования.Похоже, что Linq не очень хорош в написании полностью динамических запросов, и, по-видимому, он должен выполнять SQL где угодно в конце (поэтому SQL быстрее?).

Я создал внешние элементы управления, которые анализируют все, что мне нужнов globalvars, которые я могу затем использовать для вызова данных:

    public class GlobalVars
    {
        public static int TotalRecords = 0;
        public static int TotalPages = 0;
        public static int CurrentPage = 0;
        public static int LowerPage = 0;
        public static int UpperPage = 0;
        public static int Take = 0;
        public static int Skip = 0;
        public static string SortColumn = "CompanyName";
        public static string SortDirection = "Ascending";
    }

1 Ответ

3 голосов
/ 11 марта 2012

Использование хранимых процедур всегда будет быстрее.

Плюс я уверен, что вы можете видеть, что на самом деле гораздо проще следить за тем, что происходит в вашем коде SQL, чем Linq.

На самом деле вы имеете в виду вызов этого в выражении SQL из вашего кода.Даже тогда легче читать.И в конце дня они производят одно и то же.

Linq хорош для запроса всех готовых полученных списков.

Например, у вас есть список, но теперь вы хотите объекты, которыесовпадение WHERE x = y и новый список WHERE x = z Вы можете сделать это, не запрашивая базу данных.

Если вы собираетесь в базу данных, использовать SQL-запрос вполне подойдет.Это может затем использоваться LINQ при необходимости для дальнейшей работы со списком.

Некоторые люди могут не согласиться, но все сводится к защите.Я лично называю их с помощью операторов кода SQL.

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