So in the previous post I wrote a Linq query against the IEnumerable enabled Customers class. In that post I showed the Non-Public members and wanted to replicate them. I am glad to give here some code with replicates the original Line query.
It turns out according to this SO answer that there are two ways of using LINQ expressions, you have to use either Lambda expression or SQL-Like expression
The Original "SQL" Linq Query
Customers custs = new Customers();
var query = from Customer c in custs where c.Country != "Mexico" select new { c.CustomerId, c.CustomerName };
The Linq Query Re-Expressed With Lambdas
Customers custs = new Customers();
var query2 = custs.AsQueryable().Where(c => c.Country != "Mexico").Select((c) => new { c.CustomerId, c.CustomerName });
Inspecting the variable query shows the same Non-Public members are shown in previous post.
AsQueryable
So I named this series of posts as IEnumerable++. It seems IQueryable++ may now seem more appropriate. The hop from IEnumerable to IQueryable is achieved by the Queryable.AsQueryable method. That is the magic method that takes us away from the SQL-like syntax to the Lambda syntax.
Links
- c# - Dynamic LINQ Select method "selector" argument - Stack Overflow
- Queryable.AsQueryable Method (System.Linq) | Microsoft Docs
- Queryable.Select Method (System.Linq) | Microsoft Docs
- Queryable Class (System.Linq) | Microsoft Docs
- IQueryable Interface (System.Linq) | Microsoft Docs
- IQueryable
Interface (System.Linq) | Microsoft Docs - IQueryProvider Interface (System.Linq) | Microsoft Docs
Latest Source
So this source code is evolving, I have separated and commented out the Orders class for tidiness. It remains a console program. I will need the Orders class when I introduce joins.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Dynamic;
using System.Linq.Dynamic; // Install-Package 'System.Linq.Dynamic' NuGet
using System.Linq.Expressions;
namespace ConsoleEnumTut01
{
class Program
{
static void Main(string[] args)
{
Customers custs = new Customers();
var query = from Customer c in custs where c.Country != "Mexico" select new { c.CustomerId, c.CustomerName };
foreach (var customer in query)
{
Console.WriteLine(customer.GetType().ToString());
Console.WriteLine(customer);
}
LinqWithLambdas();
}
static void LinqWithLambdas()
{
Customers custs = new Customers();
var query2 = custs.AsQueryable().Where(c => c.Country != "Mexico").Select((c) => new { c.CustomerId, c.CustomerName });
foreach (var customer in query2)
{
Console.WriteLine(customer.GetType().ToString());
Console.WriteLine(customer);
}
}
}
class Customer
{
public int CustomerId { get; set; } // key field, unique identifier
public string CustomerName { get; set; }
public string ContactName { get; set; }
public string Country { get; set; }
public override string ToString() { return String.Format("{0} {1}", CustomerId, CustomerName); /* simple for now */ }
}
class Customers : IEnumerable<Customer>, IEnumerator<Customer>
{
// private members
List<Customer> _customers;
int _cursor;
// constructors
public Customers()
{
// delegate to Factory
_customers = CustomersListFactory.CreateCustomers();
_cursor = -1;
}
//
// Interfaces explicitly implemented
//
// IEnumerable<>
IEnumerator<Customer> IEnumerable<Customer>.GetEnumerator()
{
return this;
}
// IEnumerable
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
// IEnumerator, IEnumerator<>
Customer IEnumerator<Customer>.Current => _customers[_cursor];
object IEnumerator.Current => _customers[_cursor];
bool IEnumerator.MoveNext()
{
_cursor++;
return (_cursor < _customers.Count);
}
void IEnumerator.Reset()
{
_cursor = -1;
}
// IDisposable
void IDisposable.Dispose()
{
}
}
static class CustomersListFactory
{
public static List<Customer> CreateCustomers()
{
List<Customer> customers = new List<Customer>();
customers.Add(new Customer { CustomerId = 1, CustomerName = "Big Corp", ContactName = "Mandy", Country = "USA" });
customers.Add(new Customer { CustomerId = 2, CustomerName = "Medium Corp", ContactName = "Bob", Country = "Canada" });
customers.Add(new Customer { CustomerId = 3, CustomerName = "Small Corp", ContactName = "Jose", Country = "Mexico" });
return customers;
}
}
/*
class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public DateTime OrderDate { get; set; }
public override string ToString() { return String.Format("{0} {1} {2}", OrderId, CustomerId, OrderDate); }
}
static class OrdersListFactory
{
public static List<Order> CreateOrders()
{
List<Order> orders = new List<Order>();
orders.Add(new Order { OrderId = 420, CustomerId = 2, OrderDate = new DateTime(2018, 10, 10) });
orders.Add(new Order { OrderId = 421, CustomerId = 3, OrderDate = new DateTime(2018, 10, 11) });
orders.Add(new Order { OrderId = 422, CustomerId = 1, OrderDate = new DateTime(2018, 10, 12) });
orders.Add(new Order { OrderId = 423, CustomerId = 2, OrderDate = new DateTime(2018, 10, 13) });
return orders;
}
}
class Orders : IEnumerable<Order>, IEnumerator<Order>
{
// private members
List<Order> _orders;
int _cursor;
// constructors
public Orders()
{
// delegate to Factory
_orders = OrdersListFactory.CreateOrders();
_cursor = -1;
}
//
// Interfaces explicitly implemented
//
// IEnumerable<>
IEnumerator<Order> IEnumerable<Order>.GetEnumerator()
{
return this;
}
// IEnumerable
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
// IEnumerator, IEnumerator<>
Order IEnumerator<Order>.Current => _orders[_cursor];
object IEnumerator.Current => _orders[_cursor];
bool IEnumerator.MoveNext()
{
_cursor++;
return (_cursor < _orders.Count);
}
void IEnumerator.Reset()
{
_cursor = -1;
}
// IDisposable
void IDisposable.Dispose()
{
}
}
*/
}