The differences between IEnumerable and IQueryable, as well as the ExpressionTree Expression Tree and cronexpression expression

Source: Internet
Author: User
Tags connectionstrings

The differences between IEnumerable and IQueryable, as well as the ExpressionTree Expression Tree and cronexpression expression

For the difference between IEnumerable and IQueryable, we need to start with the generic commissioned Func <T>. Let's look at a simple example of generic delegation:

 

    class Program
    {
        static void Main(string[] args)
        {
            Func<int, bool> f = i => i > 5;
            Console.WriteLine(f(3));
            Console.WriteLine(f(10));
            Console.ReadKey();
        }
    }

 

Func <T> is "syntactic sugar". In fact, the compiler will generate a temporary method internally and then execute this method. It is equivalent to the following:

 

    class Program
    {
        static void Main(string[] args)
        {
            Func<int, bool> f = DoSth;
            Console.WriteLine(f(3));
            Console.ReadKey();
        }
        static bool DoSth(int i)
        {
            return i > 5;
        }
    }

 

Above, the path for. NET internal operation is: compile C # code → compile the compiler into the intermediate language IL → execute the JIT compilation cost locally during the runtime

 

■ Use Expression Tree

 

However, what should we do if we want to execute code at runtime?

 

. NET provides Expression Tree for us to execute code at runtime.

 

For example, the above Func <int, bool> f = I => I> 5; Expression Tree understands this Expression as follows:

 

○ F is Expression <Func <int, bool> type, level Expression <TDelegate> type
○ => Understood as the BinaryExpression type
○ => I on the left and right sides is interpreted as ParameterExpression.
○ => The 5 on the right is interpreted as ConstantExpression.

 

Therefore, if we use Expression Tree to execute code at runtime, we can write as follows:

 

    class Program
    {
        static void Main(string[] args)
        {
            //Func<int, bool> f = i => i > 5;
            ParameterExpression iParam = Expression.Parameter(typeof (int), "i");
            ConstantExpression constExp = Expression.Constant(5, typeof (int));
            BinaryExpression greaterThan = Expression.GreaterThan(iParam, constExp);
            Expression<Func<int, bool>> f = Expression.Lambda<Func<int, bool>>(greaterThan, iParam);
            Func<int, bool> myDele = f.Compile();
            Console.WriteLine(myDele(3));
            Console.WriteLine(myDele(10));
            Console.ReadKey();
        }
    }

 

■ Differences between IQueryable and IEnumerable

 

Now, let's look at an example of IEnumerable:

 

   class Program
    {
        static void Main(string[] args)
        {
            int[] intArr = new[] {1, 2, 3, 6, 8};
            IEnumerable<int> result = Enumerable.Where(intArr, i => i > 5);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }

 

Let's take a look at Enumerable, which implements the IEnumerable interface. Its definition is as follows:

 

Let's take a look at Queryable, which implements the IQueryable interface. Its definition is as follows:

 

It is found that many methods of Enumerable and Queryable have the same names, but the types of parameters received by parameters are different. The type of parameters received by Enumerable is to delegate Func <TDelegate>, the parameter type received by Querable is Expression <Func <TDelegate>, Which is Expression Tree and Expression Tree.

 

Therefore, the expression for IEnumerable <T> is determined during the compilation period, and the expression for IQueryable <T> is determined at runtime.

 

■ Understand IQueryable in the Entity Framework application instance <T>

 

First, apply the Entity Framework component in the console application.

 

Create context classes, classes, and initial data for Entity Framework:

 

    public class Person
    {
        [Key]
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
    public class MyContext : DbContext
    {
        public MyContext() : base("myConn")
        {
            Database.SetInitializer(new DbInirializer());
        }
        public DbSet<Person> People { get; set; }
    }
    public class DbInirializer : CreateDatabaseIfNotExists<MyContext>
    {
        protected override void Seed(MyContext context)
        {
            IList<Person> people = new List<Person>();
People. Add (new Person () {Name = "Zhang San", Age = 21 });
People. Add (new Person () {Name = "", Age = 22 });
People. Add (new Person () {Name = "Zhao Wu", Age = 23 });
            foreach (var item in people)
            {
                context.People.Add(item);
            }
            base.Seed(context);
        }
    }

If we go to the definition of DbSet, we can see that DbSet implements the IQueryable interface.

 

Configure the connection string.

 

<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
    <connectionStrings>
    <add name="myConn"
       connectionString="Data Source=.;User=yourusename;Password=yourpassword;Initial Catalog=MyTest;Integrated Security=True"
       providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>    

 

In the main program:

 

    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new MyContext())
            {
                foreach (var item in context.People)
                {
                    Console.WriteLine(item.Name);
                }
            }
            Console.ReadKey();
        }
    }

 

Now let's take a look at some of the features of IQueryable <T>.

 

We know that DbSet implements the IQuerayble interface, so the People attribute type of the context is IQueryable <Person>.

 

Pass,

 

IQueryable <Person> people = context. People;

 

The resulting people is an expression and an SQL statement. Now we try to print the people expression in different situations.

 

    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new MyContext())
            {
                IQueryable<Person> people = context.People;
                var r = new Random();
                Func<bool> rBool = () => r.Next()%2 == 0;
                Console.WriteLine(people);
                if (rBool())
                {
                    people = people.Where(p => p.Age > 21);
                    Console.WriteLine(people);
                }
                else
                {
                    people = people.OrderBy(p => p.Age);
                    Console.WriteLine(people);
                }
            }
            Console.ReadKey();
        }
    }


 

From this we can see that IQueryable presents an expression rather than a set. Through this expression, we can load data that meets the conditions as needed.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.