简体   繁体   中英

LINQ Group by Clause with Where clause

I am learning LINQ. Can anybody please help me to solve the following problem!

From Northwind 's Customers and Orders tables:

I want to " Find all Customers who have done more than 20 Orders "

The Query in SQL Server for the same is:

SELECT * FROM Customers WHERE CustomerID in (SELECT CustomerID FROM Orders GROUP BY CustomerID HAVING COUNT(CustomerID) > 20)

But, I could not able to write the equivalent in LINQ.

I have tried like below:

var customers = ctx.Customers.Where(o => o.CustomerID.Count() > 20).GroupBy(o => o.CustomerID);

I am geting the following error in Event Log:

Exception information: Exception type: HttpCompileException Exception message: e:\\Ashok\\WEB\\VS2012\\CSHWEB\\CSHWEB\\LINQ01.aspx(17): error CS0103: The name 'Orders' does not exist in the current context

The reason is that the dependent Orders table might not be loaded yet. But, I am not understanding how to make it work!

Your relations between objects should be properly configured. If you're using Entity Framework just mark Orders property in Customers entity as virtual this will allow lazy loading. Then your query will be much simpler. Otherwise you can still start from Orders instead of Customers :

var customers = ctx.Orders.GroupBy(c => c.CustomerID)
                             .Where(x => x.Count() > 20)
                             .SelectMany(g => g.Select(o => o.Customer));

And for customers (with virtual Orders collection) pretty straightforward:

var customers = ctx.Customers.Where(c => c.Orders.Count() > 20);

If customers and orders are related (1:MANY) and you have set up your object model to reflect this you could do:

var customers = ctx.Customers.Where(c => c.Orders.Count() > 20);

If not then:

var customerIds = ctx.Orders.GroupBy(x => x.CustomerID)
.Where(x => x.Count() > 20);
.SelectMany(x => x.CustomerID);

var customers = ctx.Customers.Where(x => customerIds.Contains(x.CustomerID));

You could do something like this:

var customers = from c in Customers where c.Orders.Count() > 20 select c;
customers.GroupBy(o => o.CustomerID);

try use join..into clause something like this

var customers = from c in ctx.Customers
                join o in ctx.Orders on c.CustomerID equals o.CustomerID into orders
                where orders.Count()>20
                select c;

In order to write to such query, you need to use a database relation (Navigation Property). This relation should be declared in your context as Customer.Orders . After then, you can use Linq to query the context. Check this out for an example which describes what you need. http://msdn.microsoft.com/en-us/library/bb425822.aspx

However you can declare context like:

public partial class Northwind : DataContext
{
   public Table<Customer> Customers;
   public Table<Order> Orders;
   public Northwind(string connection): base(connection) {}
}

and you should define your Customer class like:

[Table(Name="Customers")]
public class Customer
{
   [Column(Id=true)]
   public string CustomerID;
   ...
   private EntitySet<Order> _Orders;
   [Association(Storage="_Orders", OtherKey="CustomerID")]
   public EntitySet<Order> Orders {
      get { return this._Orders; }
      set { this._Orders.Assign(value); }
   }
}

then you can query it like the other answers said.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM