Ehsan Ghanbari

Experience, DotNet, Solutions

Note about the Deferred Execution in LINQ component

Maybe you know about the deferred execution unconsciously. This sexy phrase refers to the point of LINQ queries when it executed. Although executing the LINQ query should be considered and after doing join, group, let and every LINQ instructions, finally, it should be executed; because it will be executed in every call if you don't execute it! Take a look at the following example:

  public IEnumerable<Blog> GetAllPosts()

        {

            var executedQuery =_siteContext.Blogs.

                Where(p => p.IsDeleted == false && p.IsPublished)

                .OrderByDescending(c => c.CreationDate)

                .Include(c => c.Tags)

                .ToList();

           var count = executedQuery .Count();

           var average= executedQuery.Contains("d");

           return executedQuery ;

        }

As you can see the executed Query has been executed by .ToList() and the Count() and Contains("d") will be queried in memory and If you don't call .ToList() it will be executed in each of the mentioned LINQ methods.



Practicing different kinds of joins via Linq

I'm interested in to share these samples about different kinds of joins via LINQ. have fun!

 

 public class Brand
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Product
    {
        public int Id { get; set; }
        public int CategoryId { get; set; }
        public string Name { get; set; }
        public Brand Brand { get; set; }
    }

 

and some fake data:

 

  public class Data
    {
        static List<Brand> _brands = new List<Brand>()
            {
                new Brand() {Id = 1, Name = "Best"},
            };


        static List<Category> _categories = new List<Category>()
            {
                new Category() {Id = 1, Name = "Sextual"},
                new Category() {Id = 2, Name = "Sport"}
            };

        static List<Product> _products = new List<Product>()
            {
                new Product() {Id = 1, Name = "Candom!",CategoryId = 1, Brand=_brands.Single(b=>b.Name=="Best")},
                new Product() {Id = 2, Name = "Dildo!",CategoryId =1, Brand=_brands.Single(b=>b.Name=="Best") }
            };

 

the queries:

 

  public class InnerJoin
        {

            void Sample1()
            {
                var data = from category in _categories
                           join product in _products on category.Id equals product.CategoryId
                           select new { Category = category.Id, Product = product.Name };
            }

            void Sample2()
            {
                var data = from category in _categories
                           join product in _products on new {p = category.Name} equals new {p = product.Name = "Mature"}
                           select new
                               {
                                   category.Id,
                                   category.Name
                               };
            }
            void Sample3()
            {
                var data = from brand in _brands
                           from product in _products.Where(b => b.Brand.Name == "Best" || b.CategoryId == b.Id)
                           select new
                               {
                                   brand.Name,
                                   brand.Id
                               };
            }
          
        }

        public class LeftJoin
        {
            void Sample1()
            {
                var data = from brand in _brands
                           join product in _products on brand.Id equals product.Brand.Id into productGroup
                           from g in productGroup.DefaultIfEmpty()
                           select new
                               {
                                   brand.Id,
                                   brand.Name,
                               };
            }
        }

        public class GroupJoin
        {
            void Sample1()
            {
                var data = from category in _categories
                           join product in _products on category.Id equals product.CategoryId into productGroup
                           select productGroup;
            }
        }

        public class GroupInnerJoin
        {
            void Sampel()
            {
                var data = from category in _categories
                           join product in _products on category.Id equals product.CategoryId into productGroup
                           select new
                               {
                                   Category = category.Name,
                                   Product = from product in productGroup
                                             select product
                               };
            }
        }

        public class OuterJoin
        {
           void Sample1()
           {
               var data = from category in _categories
                          join product in _products
                              on category.Id equals product.CategoryId
                              into productGroup
                          from productCategory in productGroup.DefaultIfEmpty()
                          select new
                              {
                                  Category = category.Name,
                                  category = productCategory.Name
                              };

           }
        }


        public class LeftOuterJoin
        {
            void Sample1()
            {
                var data = from category in _categories
                           join product in _products on category.Id equals product.CategoryId into productGroup
                           select productGroup.DefaultIfEmpty(new Product() { Id = 3, Name = "Style!", CategoryId = 3 });


            }
        }
    }

 

Cheers!



How to query over Icollection<> of a type with linq

When you are implementing many to many relations in SQL, in the case of using entity framework code fist you must use Icollection<> or Ilist<> of an entity. Imagine that you have this classes, an Author class which has a collection of books

 

    public class Author
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public ICollection<Books> Books { get; set; }
    }

 

And the Books which has a collection of Authors

 

    public class Books
    {
        public int Id { get; set; }
        public string Title { get; set; }

        public ICollection<Author> Authors { get; set; }
    }

 

And this is your context class

 

    public class ContextClass : DbContext
    {
        public DbSet<Books> Books { get; set; }
        public DbSet<Author> Authors { get; set; }
    }

 

If you want you to create a repository class, to get the books by authors Id, You should act like this

 

    public class Repository
    {
        private ContextClass _contextClass = new ContextClass();
        public IEnumerable<Books> FindBookByAuthor(int authorId)
        {
            var query = _contextClass.Books.Where(b => b.Authors.Any(a => a.Id == authorId));
            return query.ToList();
        }
    }

 

In the lambda expression, you have to use any(), because you have a collection of authors in book class. That's all!

 



An overview to Linq by considering example

"Language Integrated Query (LINQ, pronounced "link") is a Microsoft .NET Framework component that adds native data querying capabilities to.NET languages, although ports exist for Java, PHP, JavaScript, and ActionScript". wikipedia

Linq provides some C# standard method that you can call them by method syntax instead of query syntax in C# development environment, very useful for retrieving information from databases by formulating queries, questions, expressed in the language. most used of those methods are Select, Join, Where, Group, Max, Min, …

 

Example one

create this class and its definition

 

   public class Profile
   {
        public string Name { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }

 

And add this Service class :

 

    public class ProfileService
    {
        public List<string> Operation()
        {
            var profiles = new List<Profile>
                {
                    new Profile {Age = 23, Name = "Ehsan", LastName = "Ghanbari"},
                    new Profile {Age = 30, Name = "Tom", LastName = "Miles"}
                };

            var query = from f in profiles where f.Age == 23 select f.Name;

            return query.ToList();
        }

 

This query returns the Name of person with 23 years old, test below queries too and sees the result

 

  var query2 = from f in profiles orderby f.Age ascending select f;
  var query3 = from f in profiles where f.Name == "Tom" select f;
  var query4 = from f in profiles where f.Age > 25 select f;
  var query5 = from f in profiles where f.LastName.StartsWith("M") select f;
  var query6 = profiles.Single(c => c.Age == 40);
  var query7 = profiles.SingleOrDefault();
  var query8 = profiles.Select(c => c.Name).ToList();

      

Example two

Book class :

 

    public class Book
    {
        public int BookId { get; set; }
        public string Name { get; set; }
        public bool IsPublished { get; set; }
    }

 

and Author class

 

    public class Author
    {
        public int AuthorId { get; set; }
        public string Name { get; set; }
        public Book Book { get; set; }
     }

 

(Notice that every author could have many books )

Create a Service class to initialize Book and Authors :

 

    public class  InitializerClass
    {
        public void Initialize()
        {
            var books = new List<Book>
                {
                    new Book {BookId = 1, Name = "DDD", IsPublished = true,PulishDate=DateTime.Now},
                    new Book {BookId = 2, Name = "Design Pattern", IsPublished = false,PulishDate=DateTime.Now}
                };

            var authors = new List<Author>
                {
                    new Author
                        {
                            AuthorId = 1,
                            Name = "Eric",
                            Book = new Book {BookId = 1, Name = "DDD", IsPublished = true}
                        },
                    new Author
                        {
                            AuthorId = 2,
                            Name = "Scott",
                            Book = new Book {BookId = 2, Name = "MVC4", IsPublished = true}
                        }
                };
          }
     }

 

Now create a method and test all of these queries an see the result:

 

var query = from a in authors
                        orderby a.AuthorId
                        from b in books
                        orderby b.BookId
                        select new { a, b };

 

Note: selects from authors and sets by Id, select from books and order by Id and finally returns the selected Items from author and Book!

 

 var query2 = from a in authors
                         join b in books on a.AuthorId equals b.BookId
                         select a;


  var query3 = from a in authors
                         where a.Book.Name == "MVC4"
                         select new { x = a.Book, a };
  var query4 = from b in books
                         join a in authors on b.BookId equals a.AuthorId
                         where b.Name == "Eric"
                         select b;
 var query5 =
                from b in books
                where b.Name == "DDD"
                select new {b.Name, b.IsPublished}
                into x
                orderby x.Name
                select x;
   var query6 =
                from b in books
                select new {b.Name, b.BookId}
                into x
                orderby x.Name
                select x;
  var query7 =
                from b in books
                orderby b.PulishDate descending
                select b;

 

example three

 Create two class named Product and Category with these definitions:

 

 public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
    }
   
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public Category Category { get; set; }
    }

 

And then add a Data Generator class to Generate some Fake Date to work with!

 

    public class ListGenerator
    {
        private List<Category> _categories;
        private List<Product> _productList;

        private void CategoryList()
        {
            _categories = new List<Category>()
                {
                    new Category
                        {
                            CategoryId = 1,
                            CategoryName = "Yammi"
                        }
                };
        }

        private void ProductList()
        {
            _productList = new List<Product>
                {
                    new Product
                        {
                            Category = _categories.Single(c => c.CategoryName == "Yammi"),
                            ProductId = 1,
                            ProductName = "cholocalte"
                        }
                };
        }
    }

 

Now Create a method to write some different queries :

 

 var query =
                from cat in _categories
                join pro in _productList on cat equals pro.Category into p
                from s in p
                select new {s.ProductName};
 var query2 =
                (from pro in _productList
                 where pro.ProductId == 2
                 select pro).First();

   var query3 =
                from pro in _productList
                group pro by pro.Category
                into proGroup
                select new {productNumber = proGroup.Count()};

 

And finally for more  information about LINQ refer to this address :

http://msdn.microsoft.com/en-us/library/bb425822.aspx



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns and I'm spending a lot of my time on architecture subject. Since 2008, I've been as a developer for companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the&nb Read More

Post Tags
Pending Blog Posts
Strategic design
Factory Pattern
time out pattern in ajax
Selectors in Jquery
using Log4net in asp.net MVC4
How to use PagedList In asp.net MVC
Redis as a cache server
Domain driven design VS model driven architecture
What's the DDD-lite?
Multiple submit buttons in asp.net MVC