private static void LINQtoDb()
        {
            #region cache query
            using (var db = new CatsDataConnection())
            {
                // LINQ to DB does not support Select joins
                // You need to join your tables explicitly

                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();
            }

            #endregion

            var stopWatch = Stopwatch.StartNew();

            // LINQ to DB
            using (var db = new CatsDataConnection())
            {
                // LINQ to DB does not support Select joins
                // You need to join your tables explicitly

                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"LINQ to DB Join: {stopWatch.Elapsed} - {cats.Count} Results");
            }
        }
Esempio n. 2
0
        public static void Fight()
        {
            Console.WriteLine("Cold And Warm Queries Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core - First Query Will Be Slow
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c =>
                                  c.BirthDate.Year > 2019 &&
                                  c.Color.Contains("B") &&
                                  c.Owner.Cats.Any(cat => cat.Age < 5) &&
                                  c.Owner.Cats.Count(cat => cat.Name.Length > 3) > 3)
                           .Select(c => new
                {
                    c.Name,
                    Cats = c.Owner
                           .Cats
                           .Count(cat =>
                                  cat.Age < 5 &&
                                  cat.Name.StartsWith("C"))
                })
                           .ToList();

                Console.WriteLine($"EF Core - First Query: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core - Second Query Will Be Fast
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c =>
                                  c.BirthDate.Year > 2019 &&
                                  c.Color.Contains("B") &&
                                  c.Owner.Cats.Any(cat => cat.Age < 5) &&
                                  c.Owner.Cats.Count(cat => cat.Name.Length > 3) > 3)
                           .Select(c => new
                {
                    c.Name,
                    Cats = c.Owner
                           .Cats
                           .Count(cat =>
                                  cat.Age < 5 &&
                                  cat.Name.StartsWith("C"))
                })
                           .ToList();

                Console.WriteLine($"EF Core - Second Query: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB - First Query Will Be Slow
            using (var db = new CatsDataConnection())
            {
                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"LINQ to DB - First Query: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB - Second Query Will Be Fast
            using (var db = new CatsDataConnection())
            {
                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"LINQ to DB - Second Query: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper - First Query
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT [c].[Name], [c].[Age]
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE (
                        SELECT COUNT(*)
                        FROM [Cats] AS [c0]
                        WHERE [o].[Id] = [c0].[OwnerId]) > 1");

                Console.WriteLine($"Dapper - First Query: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper - Second Query
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT [c].[Name], [c].[Age]
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE (
                        SELECT COUNT(*)
                        FROM [Cats] AS [c0]
                        WHERE [o].[Id] = [c0].[OwnerId]) > 1");

                Console.WriteLine($"Dapper - First Query: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            Console.WriteLine(new string('-', 50));
        }
        public static void Fight()
        {
            Console.WriteLine("Select Specific Columns Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core Getting All Columns
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c => c.Owner.Cats.Count > 1)
                           // .AsNoTracking()
                           .ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"EF Core Getting All Columns: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Getting All Columns Cached
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c => c.Owner.Cats.Count > 1)
                           // .AsNoTracking()
                           .ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"EF Core Getting All Columns Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Getting Only The Columns We Need
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c => c.Owner.Cats.Count > 1)
                           .Select(c => new CatResult
                {
                    Name = c.Name,
                    Age  = c.Age
                })
                           .ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"EF Core Getting Only The Columns We Need: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Getting Only The Columns We Need Cached
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c => c.Owner.Cats.Count > 1)
                           .Select(c => new CatResult
                {
                    Name = c.Name,
                    Age  = c.Age
                })
                           .ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"EF Core Getting Only The Columns We Need Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Joins
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Join(
                    db.Owners.Where(o => o.Cats.Count > 1),
                    c => c.OwnerId,
                    o => o.Id,
                    (c, o) => new CatResult
                {
                    Name = c.Name,
                    Age  = c.Age
                })
                           .ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"EF Core Using Joins: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting All Columns
            using (var db = new CatsDataConnection())
            {
                var cats = (from cat in db.Cats
                            join owner in db.Owners
                            on cat.OwnerId equals owner.Id
                            join ownerCat in db.Cats
                            on owner.Id equals ownerCat.OwnerId
                            into ownersWithCats
                            where ownersWithCats.Count() > 1
                            select cat).ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"LINQ to DB Getting All Columns: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting All Columns Cached
            using (var db = new CatsDataConnection())
            {
                var cats = (from cat in db.Cats
                            join owner in db.Owners
                            on cat.OwnerId equals owner.Id
                            join ownerCat in db.Cats
                            on owner.Id equals ownerCat.OwnerId
                            into ownersWithCats
                            where ownersWithCats.Count() > 1
                            select cat).ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"LINQ to DB Getting All Columns Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting Only The Columns We Need
            using (var db = new CatsDataConnection())
            {
                var cats = (from cat in db.Cats
                            join owner in db.Owners
                            on cat.OwnerId equals owner.Id
                            join ownerCat in db.Cats
                            on owner.Id equals ownerCat.OwnerId
                            into ownersWithCats
                            where ownersWithCats.Count() > 1
                            select new CatResult
                {
                    Name = cat.Name,
                    Age = cat.Age
                }).ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"LINQ to DB Getting Only The Columns We Need: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting Only The Columns We Need Cached
            using (var db = new CatsDataConnection())
            {
                var cats = (from cat in db.Cats
                            join owner in db.Owners
                            on cat.OwnerId equals owner.Id
                            join ownerCat in db.Cats
                            on owner.Id equals ownerCat.OwnerId
                            into ownersWithCats
                            where ownersWithCats.Count() > 1
                            select new CatResult
                {
                    Name = cat.Name,
                    Age = cat.Age
                }).ToDictionary(c => c.Name, c => c.Age);

                Console.WriteLine($"LINQ to DB Getting Only The Columns We Need Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper Getting All Columns
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT *
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE (
                        SELECT COUNT(*)
                        FROM [Cats] AS [c0]
                        WHERE [o].[Id] = [c0].[OwnerId]) > 1");

                Console.WriteLine($"Dapper Getting All Columns: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper Getting All Columns Cached
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT *
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE (
                        SELECT COUNT(*)
                        FROM [Cats] AS [c0]
                        WHERE [o].[Id] = [c0].[OwnerId]) > 1");

                Console.WriteLine($"Dapper Getting All Columns Cached: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper Getting Only The Columns We Need
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <CatResult>(
                    @"SELECT [c].[Name], [c].[Age]
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE (
                        SELECT COUNT(*)
                        FROM [Cats] AS [c0]
                        WHERE [o].[Id] = [c0].[OwnerId]) > 1");

                Console.WriteLine($"Dapper Getting Only The Columns We Need: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper Getting Only The Columns We Need Cached
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <CatResult>(
                    @"SELECT [c].[Name], [c].[Age]
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE (
                        SELECT COUNT(*)
                        FROM [Cats] AS [c0]
                        WHERE [o].[Id] = [c0].[OwnerId]) > 1");

                Console.WriteLine($"Dapper Getting Only The Columns We Need Cached: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Raw SQL Query
            using (var db = new CatsDbContext())
            {
                // EF Core cannot translate this query.

                try
                {
                    var cats = db.Cats
                               .FromSqlRaw(
                        @"SELECT *
                            FROM [Cats] AS [c]
                            INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                            WHERE (
                                SELECT COUNT(*)
                                FROM [Cats] AS [c0]
                                WHERE [o].[Id] = [c0].[OwnerId]) > 1")
                               .ToList();

                    Console.WriteLine($"EF Core Raw SQL Query: {stopWatch.Elapsed} - {cats.Count} Results");
                }
                catch
                {
                    Console.WriteLine("EF Core Raw SQL Query: CANNOT EXECUTE.");
                }
            }

            Console.WriteLine(new string('-', 50));
        }
Esempio n. 4
0
        public static void Fight()
        {
            Console.WriteLine("Incorrect Data Loading Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core Getting All Rows
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .ToList()
                           .Where(c => c.Name.Contains("1")); // This Where will be executed in memory.

                Console.WriteLine($"EF Core Getting All Rows: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Getting Only The Rows We Need
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c => c.Name.Contains("1"))
                           // .AsNoTracking()
                           .ToList();

                Console.WriteLine($"EF Core Getting Only The Rows We Need: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Getting Only The Rows We Need Cached
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Where(c => c.Name.Contains("1"))
                           // .AsNoTracking()
                           .ToList();

                Console.WriteLine($"EF Core Getting Only The Rows We Need Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting All Rows
            using (var db = new CatsDataConnection())
            {
                var cats = db.Cats
                           .ToList()
                           .Where(c => c.Name.Contains("1")); // This Where will be executed in memory.

                Console.WriteLine($"LINQ to DB Getting All Rows: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting Only The Rows We Need
            using (var db = new CatsDataConnection())
            {
                var cats = db.Cats
                           .Where(c => c.Name.Contains("1"))
                           .ToList();

                Console.WriteLine($"LINQ to DB Getting Only The Rows We Need: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Getting Only The Rows We Need Cached
            using (var db = new CatsDataConnection())
            {
                var cats = db.Cats
                           .Where(c => c.Name.Contains("1"))
                           .ToList();

                Console.WriteLine($"LINQ to DB Getting Only The Rows We Need Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            Console.WriteLine(new string('-', 50));
        }
Esempio n. 5
0
        public static void Fight()
        {
            Console.WriteLine("Too Many Queries Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core N+1
            using (var db = new CatsDbContext())
            {
                var owners = db.Owners
                             .Where(o => o.Name.Contains("1"))
                             .ToList();

                var total = 0;

                foreach (var owner in owners)
                {
                    var cats = db.Cats
                               .Where(c => c.OwnerId == owner.Id && c.Name.Contains("1"))
                               .ToList();

                    total += cats.Count;
                }

                Console.WriteLine($"EF Core N+1: {stopWatch.Elapsed} - {total} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Include
            using (var db = new CatsDbContext())
            {
                var owners = db.Owners
                             .Where(o => o.Name.Contains("1"))
                             .Include(o => o.Cats)
                             .ToList();

                var total = 0;

                foreach (var owner in owners)
                {
                    var cats = owner.Cats
                               .Where(c => c.Name.Contains("1"))
                               .ToList();

                    total += cats.Count;
                }

                Console.WriteLine($"EF Core Include: {stopWatch.Elapsed} - {total} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Filtered Include - Introduced in EF Core 5.0
            using (var db = new CatsDbContext())
            {
                var owners = db.Owners
                             .Where(o => o.Name.Contains("1"))
                             .Include(o => o.Cats
                                      .Where(c => c.Name.Contains("1")))
                             .ToList();

                Console.WriteLine($"EF Core Filtered Include: {stopWatch.Elapsed} - {owners.SelectMany(o => o.Cats).Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Select
            using (var db = new CatsDbContext())
            {
                var owners = db.Owners
                             .Where(o => o.Name.Contains("1"))
                             .Select(o => new
                {
                    Cats = o.Cats
                           .Where(c => c.Name.Contains("1"))
                })
                             .ToList();

                Console.WriteLine($"EF Core Select: {stopWatch.Elapsed} - {owners.SelectMany(o => o.Cats).Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Join
            using (var db = new CatsDbContext())
            {
                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"EF Core Join: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB
            using (var db = new CatsDataConnection())
            {
                // LINQ to DB does not support Select joins
                // You need to join your tables explicitly

                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"LINQ to DB Join: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Cached
            using (var db = new CatsDataConnection())
            {
                var cats = db.Owners
                           .Where(o => o.Name.Contains("1"))
                           .Join(db.Cats.Where(c => c.Name.Contains("1")),
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"LINQ to DB Join Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // RepoDB Query And In Memory Join
            using (var connection = new SqlConnection(Settings.ConnectionString).EnsureOpen())
            {
                var dbOwners = connection.Query <Owner>(o => o.Name.Contains("1"));
                var dbCats   = connection.Query <Cat>(c => c.Name.Contains("1"));

                var cats = dbOwners
                           .Join(dbCats,
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"RepoDB Query And In Memory Join: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // RepoDB Query Multiple And In Memory Join
            using (var connection = new SqlConnection(Settings.ConnectionString).EnsureOpen())
            {
                var result = connection.QueryMultiple <Owner, Cat>(
                    o => o.Name.Contains("1"),
                    c => c.Name.Contains("1"));

                var dbOwners = result.Item1.AsList();
                var dbCats   = result.Item2.AsList();

                var cats = dbOwners
                           .Join(dbCats,
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c)
                           .ToList();

                Console.WriteLine($"RepoDB Query Multiple And In Memory Join: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With EF Query
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT [o].[Id], [t].[Id], [t].[Age], [t].[BirthDate], [t].[Color], [t].[Name], [t].[OwnerId]
                    FROM[Owners] AS[o]
                    LEFT JOIN(
                        SELECT[c].[Id], [c].[Age], [c].[BirthDate], [c].[Color], [c].[Name], [c].[OwnerId]
                    FROM[Cats] AS[c]
                    WHERE CHARINDEX(N'1', [c].[Name]) > 0
                        ) AS[t] ON[o].[Id] = [t].[OwnerId]
                    WHERE CHARINDEX(N'1', [o].[Name]) > 0
                    ORDER BY[o].[Id], [t].[Id]");

                Console.WriteLine($"Dapper (EF): {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With EF Query Cached
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT [o].[Id], [t].[Id], [t].[Age], [t].[BirthDate], [t].[Color], [t].[Name], [t].[OwnerId]
                    FROM[Owners] AS[o]
                    LEFT JOIN(
                        SELECT[c].[Id], [c].[Age], [c].[BirthDate], [c].[Color], [c].[Name], [c].[OwnerId]
                    FROM[Cats] AS[c]
                    WHERE CHARINDEX(N'1', [c].[Name]) > 0
                        ) AS[t] ON[o].[Id] = [t].[OwnerId]
                    WHERE CHARINDEX(N'1', [o].[Name]) > 0
                    ORDER BY[o].[Id], [t].[Id]");

                Console.WriteLine($"Dapper (EF) Cached: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With LINQ to DB Query
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT
	                    [c_1].[Id],
	                    [c_1].[Name],
	                    [c_1].[Age],
	                    [c_1].[BirthDate],
	                    [c_1].[Color],
	                    [c_1].[OwnerId]
                    FROM
	                    [Owners] [o]
		                    INNER JOIN [Cats] [c_1] ON [o].[Id] = [c_1].[OwnerId]
                    WHERE
	                    [c_1].[Name] LIKE N'%1%' AND [o].[Name] LIKE N'%1%'"    );

                Console.WriteLine($"Dapper (LINQ to DB): {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With LINQ to DB Query Cached
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT
	                    [c_1].[Id],
	                    [c_1].[Name],
	                    [c_1].[Age],
	                    [c_1].[BirthDate],
	                    [c_1].[Color],
	                    [c_1].[OwnerId]
                    FROM
	                    [Owners] [o]
		                    INNER JOIN [Cats] [c_1] ON [o].[Id] = [c_1].[OwnerId]
                    WHERE
	                    [c_1].[Name] LIKE N'%1%' AND [o].[Name] LIKE N'%1%'"    );

                Console.WriteLine($"Dapper (LINQ to DB) cached: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Raw SQL Query
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .FromSqlRaw(
                    @"SELECT
	                        [c_1].[Id],
	                        [c_1].[Name],
	                        [c_1].[Age],
	                        [c_1].[BirthDate],
	                        [c_1].[Color],
	                        [c_1].[OwnerId]
                        FROM
	                        [Owners] [o]
		                        INNER JOIN [Cats] [c_1] ON [o].[Id] = [c_1].[OwnerId]
                        WHERE
	                        [c_1].[Name] LIKE N'%1%' AND [o].[Name] LIKE N'%1%'"    )
                           // .AsNoTracking()
                           .ToList();

                Console.WriteLine($"EF Core Raw SQL Query: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            Console.WriteLine(new string('-', 50));
        }
        public static void Fight()
        {
            Console.WriteLine("Delete Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core Makes 2 Queries - One Read and One Delete
            using (var db = new CatsDbContext())
            {
                var cat = db.Cats.Find(1);

                db.Remove(cat);

                db.SaveChanges();

                Console.WriteLine($"EF Core - 2 Queries: {stopWatch.Elapsed}");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Makes One Query - Only Delete
            using (var db = new CatsDbContext())
            {
                var cat = new Cat {
                    Id = 2
                };

                db.Remove(cat);

                db.SaveChanges();

                Console.WriteLine($"EF Core - 1 Query: {stopWatch.Elapsed}");
            }

            Console.WriteLine(new string('-', 20));

            stopWatch = Stopwatch.StartNew();

            // EF Core Delete Multiple Rows - Slow
            using (var db = new CatsDbContext())
            {
                var catsToDelete = db.Cats
                                   .Where(c => c.Age == 1)
                                   .Select(c => c.Id)
                                   .ToList();

                db.RemoveRange(catsToDelete.Select(id => new Cat {
                    Id = id
                }));

                db.SaveChanges();

                Console.WriteLine($"EF Core Delete Multiple Rows - Remove Range: {stopWatch.Elapsed} - {catsToDelete.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Delete Multiple Rows - Fast with SQL
            using (var db = new CatsDbContext())
            {
                var deleted = db.Database.ExecuteSqlInterpolated($"DELETE FROM Cats WHERE Age = {2}");

                Console.WriteLine($"EF Core Delete Multiple Rows - SQL: {stopWatch.Elapsed} - {deleted} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Plus
            using (var db = new CatsDbContext())
            {
                var catsToDelete = db.Cats
                                   .Where(c => c.Age == 3)
                                   .Delete();

                Console.WriteLine($"EF Plus: {stopWatch.Elapsed} - {catsToDelete} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Delete Multiple Rows
            using (var db = new CatsDataConnection())
            {
                var deleted = LinqToDB.LinqExtensions.Delete(db.Cats, c => c.Age == 4);

                Console.WriteLine($"LINQ to DB: {stopWatch.Elapsed} - {deleted} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // RepoDB Delete Multiple Rows
            using (var sqlConnection = new SqlConnection(Settings.ConnectionString).EnsureOpen())
            {
                var deleted = sqlConnection.Delete <Cat>(c => c.Age == 5);

                Console.WriteLine($"RepoDB Delete Multiple Rows: {stopWatch.Elapsed} - {deleted} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper
            using var connection = new SqlConnection(Settings.ConnectionString);

            var dapperDeleted = connection.Execute("DELETE FROM Cats WHERE Age = @Id", new { Id = 6 });

            Console.WriteLine($"Dapper: {stopWatch.Elapsed} - {dapperDeleted} Results");

            Console.WriteLine(new string('-', 50));
        }
        public static void Fight()
        {
            Console.WriteLine("Lazy Loading Too Many Queries Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core N+1 Lazy Loading
            using (var db = new CatsDbContext(true))
            {
                var cats = db.Cats
                           .Where(c => c.Name.Contains("1"))
                           .ToList();

                var ownerNames = new List <string>();

                // Usually in another method
                foreach (var cat in cats)
                {
                    var ownerName = cat.Owner.Name;
                    ownerNames.Add(ownerName);
                }

                Console.WriteLine($"EF Core N+1 Lazy Loading: {stopWatch.Elapsed} - {ownerNames.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Join
            using (var db = new CatsDbContext())
            {
                var ownerNames = db.Cats
                                 .Where(o => o.Name.Contains("1"))
                                 .Join(db.Owners,
                                       c => c.OwnerId,
                                       o => o.Id, (c, o) => o.Name)
                                 .ToList();

                Console.WriteLine($"EF Core Join: {stopWatch.Elapsed} - {ownerNames.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Select
            using (var db = new CatsDbContext())
            {
                var ownerNames = db.Cats
                                 .Where(c => c.Name.Contains("1"))
                                 .Select(c => c.Owner.Name)
                                 .ToList();

                Console.WriteLine($"EF Core Using Select: {stopWatch.Elapsed} - {ownerNames.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Using Select Cached
            using (var db = new CatsDbContext())
            {
                var ownerNames = db.Cats
                                 .Where(c => c.Name.Contains("1"))
                                 .Select(c => c.Owner.Name)
                                 .ToList();

                Console.WriteLine($"EF Core Using Select Cached: {stopWatch.Elapsed} - {ownerNames.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB
            using (var db = new CatsDataConnection())
            {
                // LINQ to DB does not support Select joins
                // You need to join your tables explicitly

                var ownerNames = db.Cats
                                 .Where(o => o.Name.Contains("1"))
                                 .Join(db.Owners,
                                       c => c.OwnerId,
                                       o => o.Id, (c, o) => o.Name)
                                 .ToList();

                Console.WriteLine($"LINQ to DB Join: {stopWatch.Elapsed} - {ownerNames.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Cached
            using (var db = new CatsDataConnection())
            {
                // LINQ to DB does not support Select joins
                // You need to join your tables explicitly

                var ownerNames = db.Cats
                                 .Where(o => o.Name.Contains("1"))
                                 .Join(db.Owners,
                                       c => c.OwnerId,
                                       o => o.Id, (c, o) => o.Name)
                                 .ToList();

                Console.WriteLine($"LINQ to DB Join Cached: {stopWatch.Elapsed} - {ownerNames.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // RepoDB Query And In Memory Join
            using (var connection = new SqlConnection(Settings.ConnectionString).EnsureOpen())
            {
                var dbOwners = connection.QueryAll <Owner>();
                var dbCats   = connection.Query <Cat>(c => c.Name.Contains("1"));

                var cats = dbOwners
                           .Join(dbCats,
                                 o => o.Id,
                                 c => c.OwnerId, (o, c) => c.Name)
                           .ToList();

                Console.WriteLine($"RepoDB Query And In Memory Join: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With EF Query
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT [o].[Name]
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE CHARINDEX(N'1', [c].[Name]) > 0");

                Console.WriteLine($"Dapper (EF): {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With EF Query Cached
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT [o].[Name]
                    FROM [Cats] AS [c]
                    INNER JOIN [Owners] AS [o] ON [c].[OwnerId] = [o].[Id]
                    WHERE CHARINDEX(N'1', [c].[Name]) > 0");

                Console.WriteLine($"Dapper (EF) Cached: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With LINQ to DB Query
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT
	                    [o_1].[Name]
                    FROM
	                    [Cats] [o_2]
		                    INNER JOIN [Owners] [o_1] ON [o_2].[OwnerId] = [o_1].[Id]
                    WHERE
	                    [o_2].[Name] LIKE N'%1%'"    );

                Console.WriteLine($"Dapper (LINQ to DB): {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // Dapper With LINQ to DB Query Cached
            using (var connection = new SqlConnection(Settings.ConnectionString))
            {
                var cats = connection.Query <Cat>(
                    @"SELECT
	                    [o_1].[Name]
                    FROM
	                    [Cats] [o_2]
		                    INNER JOIN [Owners] [o_1] ON [o_2].[OwnerId] = [o_1].[Id]
                    WHERE
	                    [o_2].[Name] LIKE N'%1%'"    );

                Console.WriteLine($"Dapper (LINQ to DB) cached: {stopWatch.Elapsed} - {cats.Count()} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Raw SQL Query
            using (var db = new CatsDbContext())
            {
                // EF Core cannot translate this query.

                try
                {
                    var cats = db.Cats
                               .FromSqlRaw(
                        @"SELECT *
                            FROM
	                            [Cats] [o_2]
		                            INNER JOIN [Owners] [o_1] ON [o_2].[OwnerId] = [o_1].[Id]
                            WHERE
	                            [o_2].[Name] LIKE N'%1%'"    )
                               .ToList();

                    Console.WriteLine($"EF Core Raw SQL Query: {stopWatch.Elapsed} - {cats.Count} Results");
                }
                catch
                {
                    Console.WriteLine("EF Core Raw SQL Query: CANNOT EXECUTE.");
                }
            }

            Console.WriteLine(new string('-', 50));
        }
Esempio n. 8
0
        public static void Fight()
        {
            Console.WriteLine("Inner Query Battle");

            var stopWatch = Stopwatch.StartNew();

            // EF Core Inner Query (Depends On EF Version - Optimized After 3.0)
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Select(c => new CatSiblingsResult
                {
                    Id       = c.Id,
                    Name     = c.Name,
                    Siblings = c.Owner.Cats
                               .Where(s => s.Id != c.Id)
                               .Select(s => s.Name)
                               .ToList()
                })
                           .ToList();

                Console.WriteLine($"EF Core Inner Query: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core Inner Query Cached (Depends On EF Version - Optimized After 3.0)
            using (var db = new CatsDbContext())
            {
                var cats = db.Cats
                           .Select(c => new CatSiblingsResult
                {
                    Id       = c.Id,
                    Name     = c.Name,
                    Siblings = c.Owner.Cats
                               .Where(s => s.Id != c.Id)
                               .Select(s => s.Name)
                               .ToList()
                })
                           .ToList();

                Console.WriteLine($"EF Core Inner Query Cached: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // EF Core No Inner Query - In Memory Calculation
            using (var db = new CatsDbContext())
            {
                var dbCats = db.Cats
                             .Select(c => new
                {
                    c.Id,
                    c.Name,
                    c.OwnerId
                })
                             .ToList();

                // Evaluated in memory.
                var cats = dbCats
                           .GroupJoin(
                    dbCats,
                    c => c.OwnerId,
                    s => s.OwnerId,
                    (f, s) => new CatSiblingsResult
                {
                    Id       = f.Id,
                    Name     = f.Name,
                    Siblings = s
                               .Where(si => si.Id != f.Id)
                               .Select(si => si.Name)
                               .ToList()
                })
                           .ToList();

                Console.WriteLine($"EF Core No Inner Query - In Memory Calculation: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            stopWatch = Stopwatch.StartNew();

            // LINQ to DB Does Not Allow Inner Queries
            using (var db = new CatsDataConnection())
            {
                var dbCats = db.Cats
                             .Select(c => new
                {
                    c.Id,
                    c.Name,
                    c.OwnerId
                })
                             .ToList();

                // Evaluated in memory.
                var cats = dbCats
                           .GroupJoin(
                    dbCats,
                    c => c.OwnerId,
                    s => s.OwnerId,
                    (f, s) => new CatSiblingsResult
                {
                    Id       = f.Id,
                    Name     = f.Name,
                    Siblings = s
                               .Where(si => si.Id != f.Id)
                               .Select(si => si.Name)
                               .ToList()
                })
                           .ToList();

                Console.WriteLine($"LINQ to DB No Inner Query - In Memory Calculation: {stopWatch.Elapsed} - {cats.Count} Results");
            }

            Console.WriteLine(new string('-', 50));
        }