Когда я должен использовать LINQ для C#? [закрытый]

34
задан Taylor Leese 8 February 2010 в 18:13
поделиться

15 ответов

Я обнаруживаю, что я использую Linq только в любое время, когда я бы предварительно написал цикл для заполнения контейнера. Я использую Linq для SQL как My Orm и много LINQ везде еще.

Вот маленький фрагмент, который я написал для класса помощника Active Directory, который узнает, если конкретный пользователь является определенной группой. Обратите внимание на использование любого () метода для итерации по поводу групп авторизации пользователя, пока не найдет один с соответствующим SID. Гораздо более чистый код, чем альтернативы.

private bool IsInGroup( GroupPrincipal group, UserPrincipal user )
{
    if (group == null || group.Sid == null)
    {
        return false;
    }
    return user.GetAuthorizationGroups()
               .Any( g => g.Sid != null && g.Sid.CompareTo( group.Sid ) == 0 );
}

Альтернатива:

private bool IsInGroup( GroupPrincipal group, UserPrincipal user )
{
    if (group == null || group.Sid == null)
    {
        return false;
    }
    bool inGroup = false;
    foreach (var g in user.GetAuthorizationGroups())
    {
         if ( g => g.Sid != null && g.Sid.CompareTo( group.Sid ) == 0 )
         {
            inGroup = true;
            break;
         }
    }
    return inGroup;
}

или

private bool IsInGroup( GroupPrincipal group, UserPrincipal user )
{
    if (group == null || group.Sid == null)
    {
        return false;
    }

    foreach (var g in user.GetAuthorizationGroups())
    {
         if ( g => g.Sid != null && g.Sid.CompareTo( group.Sid ) == 0 )
         {
            return true;
         }
    }
    return false;
}

вот фрагмент, который делает поиск против хранилища, заказы и преобразует первые 10 совпадающих бизнес-объектов в модель вида ( расстояние - левенштейн. Редактировать расстояние уникального идентификатора модели сопоставления из параметра DoankeId).

model.Results = this.Repository.FindGuestByUniqueID( uniqueID, withExpired )
                               .OrderBy( g => g.Distance )
                               .Take( 10 )
                               .ToList()
                               .Select( g => new GuestGridModel( g ) );
19
ответ дан 27 November 2019 в 16:27
поделиться

Еще один момент для добавления ко всем, что является своего рода суммарную точку. Вы можете видеть из вышесказанного, что он используется для удобства и краткости и может быть использован с коллекциями, SQL, XML (и все остальное, что заботится о реализации поставщика LINQ), но лучше всего, только для того, чтобы узнать синтаксис LINQ один раз и это Переносится на все эти полезные технологические области.

0
ответ дан 27 November 2019 в 16:27
поделиться

Необходимо ли это делать с помощью вызова функции? Всякий раз, когда мне нужна эта функциональность, я просто использую:

checksum(newid())

Это будет генерировать отрицательные числа - если они должны быть положительными, вы можете использовать

abs(checksum(newid()))
-121--3095716-

Я считаю полезным преобразовать/« проецировать »данные, прежде чем связывать их с сеткой только для чтения.

-121--1855964-

Набор языковых функций LINQ не так легко реплицируется в коде C # 2.0, без методов расширения, лямбда-выражений и даже без операторов запроса. Весь пункт LINQ в том, что у вас есть какая-то интегрированная версия запросов, где вы используете компилятор для проверки их работоспособности. Другим важным пунктом является унификация взглядов на различные источники данных, будь то база данных или коллекция в памяти. Вы можете жить без LINQ, так же как вы можете жить без любой другой функции языка и кода в Assembler, но есть очевидные преимущества, которые трудно контролировать;)

0
ответ дан 27 November 2019 в 16:27
поделиться

Для меня я в значительной степени использую его только для доступа к базам данных. Я почти никогда не запрашивает XML или список.

0
ответ дан 27 November 2019 в 16:27
поделиться

Я бы повернул вопрос вокруг: Можете ли вы показать нам, как вы будете эмулировать функции Linq без него? У меня проблемы с мышлением о том, что он не не огромная помощь.

Например, я увидел что-то вроде этого в последнее время:

foreach (var person in people.OrderBy(p => p.Company)
                             .ThenBy(p => p.LastName)
                             .ThenBy(p => p.FirstName)) {
    ...
}

Я думаю, он мог бы использовать массивов .sort , создал делегат, который проверил поля в правильном порядке (назад от письменного, верно? ), а затем просто жил с тем, что он когда-либо работал только над массивами. Кажется, что это будет намного дольше, сложнее поддерживать и менее гибко.

3
ответ дан 27 November 2019 в 16:27
поделиться

Взгляните на любой из множества ответов, которые Джон Скит дает на вопросы Linq, и вы увидите, насколько на самом деле универсален и полезен Linq.

https://stackoverflow.com/search?q=user:22656+ [linq]

2
ответ дан 27 November 2019 в 16:27
поделиться

Я верю, что вы хотите что-то такое:

public partial class Sample: UserControl
{
    public event EventHandler TextboxValidated;

    public Sample()
    {
        InitializeComponent();
    }


    private void TextBox_Validated(object sender, EventArgs e)
    {
        // invoke UserControl event here
        if (this.TextboxValidated != null) this.TextboxValidated(sender, e);
    }
}

И затем на вашей форме:

public partial class MainForm : Form
{
    private Sample sampleUserControl = new Sample();

    public MainForm()
    {
        this.InitializeComponent();
        sampleUserControl.TextboxValidated += new EventHandler(this.CustomEvent_Handler);
    }
    private void CustomEvent_Handler(object sender, EventArgs e)
    {
        // do stuff
    }
}
-121--1642055-
>>> [m.groupdict() for m in re.finditer('(?P<b>.b.)|(?P<i>.i.)', 'abcdefghijk')]
[{'i': None, 'b': 'abc'}, {'i': 'hij', 'b': None}]

Кажется, работает хорошо, хотя если у вас есть много групп, проверяющих, какая из них не Нет может стать утомительным.

При этом будут найдены все .b. и все .i. соответствует в последовательности. Если вы хотите быть уверены, что он нашел один из каждого вы должны будете проверить это вручную, тоже.

-121--4518441-

Посмотрите на ReSharper, если вы еще не сделали этого. В ней много намеков на "... конвертировать в синтаксис LINQ ", чтобы он мог показать вам вещь или две вещи, которые вы не учитывали при обучении.:)

1
ответ дан 27 November 2019 в 16:27
поделиться

Я использую LINQ для набора данных для работы с DataTables. Детары являются общими хранилищами данных, где я часто хранят значения E.g. из загруженного файла CSV. Это гораздо более читаемое и удобное для использования LINQ для запроса или соединения данных вместо «грубой силы» с заводом.

4
ответ дан 27 November 2019 в 16:27
поделиться

Книга Essential LINQ обеспечивает отличное резюме абзаца преимущества LINQ:

LINQ делает более чем просто добавлять новые Особенности к языку. Это вводит деформативный стиль программирование в язык C #. То Декларативная модель программирования позволяет разработчики для кода ремесла, который Уктунно запечатлеть их намерение, не заставляя их беспокоиться о порядок, в котором происходят события, или их точное реализация. Это позволяет разработчикам указывать, что они хочу сделать, а не то, как это будет Выполнено.

10
ответ дан 27 November 2019 в 16:27
поделиться

Вы правы, редко очень трудно повторить функции в регулярном C #. Это то, что они называют синтаксическим сахаром. Это только о удобстве. Вы знаете о автоматических свойствах? Те, которые позволяют вам написать Пользователь общего класса {Public INT ID {GET; набор; }} Это чрезвычайно легко реплицироваться в «регулярном» C # код. Даже так, автоматические свойства все еще потрясающие;)

Фильтрация и сортировка в значительной степени являются ядром LINQ. Подумайте, что у вас есть список пользователей, называемых, ну пользователей , и вы хотите найти те, кто вошел в систему сегодня, и отображать их в порядке совсем недавно в системе. До LINQ, вы Вероятно, сделайте что-то вроде создания нового списка, который вы заполняете на основе исходного списка, итаив его, добавив то, что отвечает критериям, а затем реализует какой-то Impartable . Теперь вы можете просто сделать:

users = users.Where(u => u.LastLoggedIn.Date = DateTime.Today)
             .OrderBy(u => u.LastLoggedIn).ToList();

удобство =)

7
ответ дан 27 November 2019 в 16:27
поделиться

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

var circles =
        from s in allShapes
        where s.Type == ShapeTypes.Circle
        select s;

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

LINQ также может использоваться с базами данных, но я на самом деле найду, я не делаю это очень много. На каждого его / ее собственного, я думаю.

12
ответ дан 27 November 2019 в 16:27
поделиться

Это зависит от того, что вы имеете в виду LINQ.

Это linq-to-sql? В этом случае это ORM со всеми такими же преимуществами, которые приходят с использованием любого другого ORM. Я не использую это много и не могу сказать больше.

Это linq-to-объекты? В этом случае вы действительно говорите о коллекции других вещей: методы расширения, ленивые итераторы и синтаксис понимания запроса. Это введение в мир функционального программирования. Мне больше нельзя использовать для синтаксиса понимания запроса, но для остальных я могу наилучшим образом продемонстрировать с примером.

Допустим, вы хотите прочитать файл в строке по строке. Для каждой строки вы хотите проверить, соответствует ли он некоторым критериям, преобразуйте часть этих строк в целое число и суммируют первые 10 этих целых чисел, которые также в пределах определенного диапазона. Вот старый способ, которым вы сделали это:

int SumXValues(string filename)
{
    string line;
    int sum = 0;
    int count = 0;
    using (var rdr = new StreamReader(filename))
    {

        while ( (line = rdr.ReadLine()) != null && count < 10)
        {
           int val;
           if (int.TryParse(line.Substring(3,3))
           {
               if (val > 4 && val < 25)
               {
                    sum += val;
                    count ++;
               }
            }
        }
    }
    return sum;
}

Вот новый способ:

IEnumerable<string> ReadLines(string filename)
{
    string line;
    using (var rdr = new StreamReader(filename))
        while ( (line = rdr.ReadLine()) != null)
           yield return line;
}

int SumXValues(string filename)
{
    return ReadLines(filename)
               .Select(l => l.Substring(3,3))
               .Where(l => int.TryParse(l))
               .Select(i => int.Parse(i))
               .Where(i => i > 4 && i < 16)
               .Take(10)
               .Sum(i => i);
}

Обратите внимание, что новый код на самом деле короче. Но почему это также лучше? Есть (как минимум) 4 причины:

  • , надеюсь, это очевидно, как повторно использование функции readlines. Вы также можете учитывать больше, но точка - показать, как этот стиль помогает вам повторно использовать больше кода.
  • Это масштабируется лучше. Обратите внимание на все привязыванные вызовы функций в этой последней функции. Вы знаете, сколько раз этот код будет итератор по линии в вашем файле? Ровно один раз! На самом деле даже не так долго, как оно остановит чтение из файла после принятия первых 10 предметов. И если вы измените его, чтобы вернуть перечисленное время, а затем использовать это в другом месте с другими методами расширения? Все еще один раз! Это позволяет создавать, смешивать и повторно перемешать ваши результаты запроса во время выполнения без дорогостоящих дополнительных проходов в ваших списках.
  • Это более удобно. Если критерии изменяются, легко определить точное «правило» (если вы будете получать), что вы заботитесь и измените только эту часть.
  • Это более читаемо. Это позволяет выразить код с точки зрения того, что он делает, а не то, как он это делает.
16
ответ дан 27 November 2019 в 16:27
поделиться

Да, вы можете легко использовать LINQ to Objects, используя альтернативный код, и это несложно. Мне нравится семантика лямбда-выражений, и она действительно объединяет несколько строк кода в одну. Но многие операции вы можете выполнять со своим собственным кодом, за исключением некоторых более крупных операций (объединение, пересечение и т. Д.), Которые легче выполнять с LINQ.

У LINQ есть и другие особенности; LINQ to XML упрощает работу с XML-данными. Мне он очень нравится больше, чем предыдущие доступные объекты.

LINQ to SQL и ADO.NET Entity Framework (с LINQ to Entities) представляют собой объектно-реляционные сопоставители, которые могут сопоставляться с таблицами базы данных и действовать как хранимые процедуры и наборы данных ADO.NET, так что это очень хорошая альтернатива. чем слабые наборы данных / таблицы данных, и мне тоже нравится это над строго типизированными наборами данных / таблицами.

HTH.

2
ответ дан 27 November 2019 в 16:27
поделиться

Считаю полезным преобразовывать/"проектировать" данные перед их привязкой к сетке для целей только чтения.

0
ответ дан 27 November 2019 в 16:27
поделиться

Квотирование целых чисел в SQL имеет лишь незначительный штраф за производительность. Удаление кавычек намного меньше работы, чем преобразование представления ASCII в двоичное целое число.

Поэтому я бы сказал, что это вполне приемлемо, особенно для структуры RAD.

-121--4349494-

Можно создать консольное приложение, а затем изменить его свойства в параметрах настройки проекта на приложение Windows (а не консоль). Также можно создать приложение Windows Forms, которое не создает формы.

-121--4716432-

Кто-то упомянул, что LINQ является декларативным стилем программирования. Я просто хотел расширить это.

Одним из способов использования LINQ является запись тестового кода oracle. Очень важно, чтобы тестовый код был простым и как можно ближе к «очевидно правильному», иначе он будет иметь столько ошибок, сколько он должен проверить. С одной конкретной функцией, которую я тестирую сейчас, я написал небольшой список наборов понятий, которые точно описывают, как я ожидаю, что функция будет работать. Благодаря LINQ преобразование этих понятий в код становится тривиально простым:

A = all items
B = [x in A: x.Type = selectedtype, x.Source = "sourceA"]
C = [x in A: x.Source = "sourceB"]
D = B union C

В коде:

IEnumerable<MyClass> SetB(IEnumerable<MyClass> allItems, MyType type)
{
  var result = from item in allItems
               where item.Type == type && item.Source == "sourceA"
               select item;
  return result;
}

IEnumerable<MyClass> SetC(IEnumerable<MyClass> allItems)
{
  var result = from item in allItems
               where item.Source == "sourceB"
               select item;
  return result;
}

IEnumerable<MyClass> SetD(IEnumerable<MyClass> allItems, MyType type)
{
  var setB = SetB(allItems, type);
  var setC = SetC(allItems);
  return setB.Union(setC);
}

Хотя все еще немного более подробным, чем математические выражения, гораздо проще и проще называть «очевидно правильным», чем императивный код. Код LINQ является декларативным, как и математический код. Меньше перевода, ближе к spec. LINQ, когда используется соответствующим образом, в значительной степени язык «Делать то, что я имею в виду».

Обратите внимание, что я не буду писать фактический код в этом пути. Производительность не является требованием для тестового кода, но это для реального кода, поэтому реальный код по-прежнему должен быть хранимой процедурой SQL.

1
ответ дан 27 November 2019 в 16:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: