Examples done in LINQPad

Northwind.Repository.Queries.OrderSalesQuery.cs
Simple Query Object


public class OrderSalesQuery : QueryObject<Order>
{
    public decimal Amount { get; set; }
    public string Country { get; set; }
    public DateTime FromDate { get; set; }
    public DateTime ToDate { get; set; }

    public override Expression<Func<Order, bool>> Query()
    {
        return (x => 
            x.OrderDetails.Sum(y => y.UnitPrice) > Amount &&
            x.OrderDate >= FromDate &&
            x.OrderDate <= ToDate &&
            x.ShipCountry == Country);
    }
}


Querying with the OrderSalesQuery.cs


var orderRepository = new Repository<Order>(this);
	
var orders = orderRepository
	.Query(new OrderSalesQuery(){ 
		Amount = 100, 
		Country = "USA",
		FromDate = DateTime.Parse("01/01/1996"), 
		ToDate = DateTime.Parse("12/31/1996" )
	})
	.Select();



Northwind.Repository.Queries.CustomerLogisticsQuery.cs
Fluent Query Object


    public class CustomerLogisticsQuery : QueryObject<Customer>
    {
        public CustomerLogisticsQuery FromCountry(string country)
        {
            Add(x => x.Country == country);
            return this;
        }

        public CustomerLogisticsQuery LivesInCity(string city)
        {   
            Add(x => x.City == city);
            return this;
        }
    }


Northwind.Repository.Queries.CustomerSalesQuery.cs
Fluent Query Object


    public class CustomerSalesQuery : QueryObject<Customer>
    {
        public CustomerSalesQuery WithPurchasesMoreThan(decimal amount)
        {
            Add(x => x.Orders
                .SelectMany(y => y.OrderDetails)
                .Sum(z => z.UnitPrice * z.Quantity) > amount);

            return this;
        }

        public CustomerSalesQuery WithQuantitiesMoreThan(decimal quantity)
        {
            Add(x => x.Orders
                .SelectMany(y => y.OrderDetails)
                .Sum(z => z.Quantity) > quantity);

            return this;
        }
    }


Using the reusable CustomerLogisticsQuery and CustomerSalesQuery together by chaining them together.


var customerRepository = new Repository<Customer>(this);

var query1 = new CustomerLogisticsQuery()
	.LivesInCity("London");

var query2 = new CustomerSalesQuery()
	.WithPurchasesMoreThan(100)
	.WithQuantitiesMoreThan(10);

customerRepository
	.Query(query1.And(query2))
	.Select()
	.Dump();

Last edited Feb 24, 2014 at 4:37 AM by lelong37, version 10