LoveRead.info » Книги » Разная литература » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

178 0 18:04, 26-08-2023
Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
26 август 2023

Книга Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читать онлайн бесплатно без регистрации

В 10-м издании книги описаны новейшие возможности языка C# 9 и .NET 5 вместе с подробным "закулисным" обсуждением, призванным расширить навыки критического мышления разработчиков, когда речь идет об их ремесле. Книга охватывает ASP.NET Core, Entity Framework Core и многое другое наряду с последними обновлениями унифицированной платформы .NET, начиная с улучшений показателей производительности настольных приложений Windows в .NET 5 и обновления инструментария XAML и заканчивая расширенным рассмотрением файлов данных и способов обработки данных. Все примеры кода были переписаны с учетом возможностей последнего выпуска C# 9.

    1 ... 297 298 299 300 301 302 303 304 305 ... 407
    Перейти на страницу:
    class="p1">    => Context.Customers.SingleOrDefault());

    }

    Предыдущий запрос LINQ транслируется в такой код SQL:

    SELECT TOP(2) [c].[Id], [c].[TimeStamp], [c].[FirstName], [c].[FullName],

                  [c].[LastName] FROM [Dbo].[Customers] AS [c]

    Если никакие данные не возвращаются в случае применения SingleOrDefault(), то результатом будет null, а не исключение:

    [Fact]

    public void SingleOrDefaultShouldReturnDefaultIfNoneMatch()

    {

      // Expression<Func<Customer>> - это лямбда-выражение.

      Expression<Func<Customer, bool>> expression = x => x.Id == 10;

      // Возвращается null, когда ничего не найдено.

      var customer = Context.Customers.SingleOrDefault(expression);

      Assert.Null(customer);

    }

    Предыдущий запрос LINQ транслируется в такой код SQL:

    SELECT TOP(1) [c].[Id], [c].[TimeStamp], [c].[FirstName], [c].[FullName],

                  [c].[LastName] FROM [Dbo].[Customers] AS [c]

    WHERE [c].[Id] = 10

    Глобальные фильтры запросов

    Вспомните о наличии для сущности Car глобального фильтра запросов, который отбрасывает данные об автомобилях со значением свойства IsDrivable, равным false:

    modelBuilder.Entity<Car>(entity =>

    {

      entity.HasQueryFilter(c => c.IsDrivable);

      ...

    });

    Откройте файл класса CarTests.cs и добавьте показанный далее тест (все тесты в последующих разделах находятся в СаrTests.cs, если не указано иначе):

    [Fact]

    public void ShouldReturnDrivableCarsWithQueryFilterSet()

    {

      IQueryable<Car> query = Context.Cars;

      var qs = query.ToQueryString();

      var cars = query.ToList();

      Assert.NotEmpty(cars);

      Assert.Equal(9, cars.Count);

    }

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

    SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName],

           [i].[TimeStamp] FROM [dbo].[Inventory] AS [i]

    WHERE [i].[IsDrivable] = CAST(1 AS bit)

    На заметку! Как вскоре будет показано, глобальные фильтры запросов также применяются при загрузке связанных сущностей и при использовании методов FromSqlRaw() и FromSqlInterpolated().

    Отключение глобальных фильтров запросов

    Чтобы отключить глобальные фильтры запросов для сущностей в запросе, добавьте к запросу LINQ вызов метода IgnoreQueryFilters(). Он заблокирует все фильтры для всех сущностей в запросе. Если есть несколько сущностей с глобальными фильтрами запросов и некоторые фильтры сущностей нужны, тогда потребуется поместить их в методы Where() оператора LINQ. Добавьте в файл класса CarTests.cs приведенный ниже тест, который отключает фильтр запросов и возвращает все записи:

    [Fact]

    public void ShouldGetAllOfTheCars()

    {

      IQueryable<Car> query = Context.Cars.IgnoreQueryFilters();

      var qs = query.ToQueryString();

      var cars = query.ToList();

      Assert.Equal(10, cars.Count);

    }

    Как и можно было ожидать, в сгенерированном коде SQL больше нет конструкции WHERE, устраняющей записи для неуправляемых автомобилей:

    SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName],

           [i].[TimeStamp] FROM [dbo].[Inventory] AS [i]

    Фильтры запросов для навигационных свойств

    Помимо глобального фильтра запросов для сущности Car был добавлен фильтр запросов к свойству CarNavigation сущности Order:

    modelBuilder.Entity<Order>().HasQueryFilter(e => e.CarNavigation!.IsDrivable);

    Чтобы увидеть его в действии, добавьте в файл класса OrderTests.cs следующий тест:

    [Fact]

    public void ShouldGetAllOrdersExceptFiltered()

    {

        var query = Context.Orders.AsQueryable();

        var qs = query.ToQueryString();

        var orders = query.ToList();

        Assert.NotEmpty(orders);

        Assert.Equal(4,orders.Count);

    }

    Вот сгенерированный код SQL:

    SELECT [o].[Id], [o].[CarId], [o].[CustomerId], [o].[TimeStamp]

    FROM [Dbo].[Orders] AS [o]

    INNER JOIN (

        SELECT [i].[Id], [i].[IsDrivable]

        FROM [dbo].[Inventory] AS [i]

        WHERE [i].[IsDrivable] = CAST(1 AS bit)rn) AS [t]

        ON [o].[CarId] = [t].[Id]

    WHERE [t].[IsDrivable] = CAST(1 AS bit)

    Поскольку навигационное свойство CarNavigation является обязательным, механизм трансляции запросов использует конструкцию INNER JOIN, исключая записи Order, где Car соответствует неуправляемому автомобилю. Для возвращения всех записей добавьте в запрос LINQ вызов IgnoreQueryFilters().

    Энергичная загрузка связанных данных

    В предыдущей главе объяснялось, что сущности, которые связаны через навигационные свойства, могут создаваться в одном запросе с применением энергичной загрузки. Метод Include() указывает соединение со связанной сущностью, а метод ThenInclude() используется для последующих соединений. Оба метода будут задействованы в рассматриваемых далее тестах. Как упоминалось ранее, когда методы Include()/ThenInclude() транслируются в SQL, для обязательных отношений применяется внутреннее соединение, а для необязательных — левое соединение.

    Поместите в файл класса CarTests.cs следующий тест, чтобы продемонстрировать одиночный вызов Include():

    [Fact]

    public void ShouldGetAllOfTheCarsWithMakes()

    {

     IIncludableQueryable<Car, Make?> query =

      Context.Cars.Include(c => c.MakeNavigation);

      var queryString = query.ToQueryString();

      var cars = query.ToList();

      Assert.Equal(9, cars.Count);

    }

    Тест добавляет к результатам свойство MakeNavigation, выполняя внутреннее соединение с помощью показанного ниже кода SQL. Обратите внимание, что глобальный фильтр запросов действует:

    SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName],

           [i].[TimeStamp], [m].[Id], [m].[Name], [m].[TimeStamp]

    FROM [dbo].[Inventory] AS [i]

    INNER JOIN [dbo].[Makes] AS [m] ON [i].[MakeId] = [m].[Id]

    WHERE [i].[IsDrivable] = CAST(1 AS bit)

    Во втором тесте используется два набора связанных данных. Первый — это получение информации Make (как и в предыдущем тесте), а второй — получение сущностей Order и затем присоединенных к ним сущностей Customer. Полный тест также отфильтровывает записи Car, для которых есть записи Order. Для необязательных отношений генерируются левые соединения:

    [Fact]

    public void ShouldGetCarsOnOrderWithRelatedProperties()

    {

      IIncludableQueryable<Car, Customer?> query = Context.Cars

        .Where(c => c.Orders.Any())

        .Include(c => c.MakeNavigation)

        .Include(c => c.Orders).ThenInclude(o => o.CustomerNavigation);

      var queryString = query.ToQueryString();

      var cars = query.ToList();

      Assert.Equal(4, cars.Count);

      cars.ForEach(c =>

      {

        Assert.NotNull(c.MakeNavigation);

        Assert.NotNull(c.Orders.ToList()[0].CustomerNavigation);

      });

    }

    Вот сгенерированный запрос:

    SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName],

           [i].[TimeStamp], [m].[Id], [m].[Name], [m].[TimeStamp], [t0].[Id],

           [t0].[CarId], [t0].[CustomerId], [t0].[TimeStamp], [t0].[Id0],

           [t0].[TimeStamp0], [t0].[FirstName], [t0].[FullName],

        [t0].[LastName], [t0].[Id1]

    FROM [dbo].[Inventory] AS [i]

         INNER JOIN [dbo].[Makes] AS [m] ON [i].[MakeId]=[m].[Id]

         LEFT JOIN(SELECT [o].[Id], [o].[CarId], [o].[CustomerId], [o].[TimeStamp],

    1 ... 297 298 299 300 301 302 303 304 305 ... 407
    Перейти на страницу:
    1. Жалоба
    Отзывы - 0

    Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


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

    • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
    • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
    • 3. Просьба отказаться от нецензурной лексики.
    • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

    Надеемся на Ваше понимание и благоразумие. С уважением, администратор LoveRead.info.


    Установить VPN и читай слушай бесплатно

    Новые отзывы

    1. Людмила Хофман Людмила Хофман10 июнь 22:13 У меня перевернулся мир после прочтения ваших книг! Так приятно и чисто на душе, ведь по сути неважно кто с кем , а только любовь... Долгая игра - Рейчел Рид
    2. Анна Анна08 июнь 11:28 Спасибо за новую историю жизни и любви на сайте,прочитала с удовольствием .... Давай поженимся - Юлия Резник
    3. Елена Елена08 июнь 11:13 Прочла несколько романов этого, без сомнения, талантливого автора. Впечатление прекрасное, но хотелось бы когда-нибудь прочесть... Предатель. Ты врал мне годами - Арина Арская
    Все комметарии
    Новинки бесплатной онлайн библиотеки