Question

I am using EntityFramework 4.3.1 and Database first with dbcontext.

Let's say I have 2 tables: Customer and Order with a 1 to many relationship between Customer and Order.

I have two queries that I want to run using EntityFramework to get back specific information for different web pages.

The first is: Get all Customers who have placed orders since a specific date.

So, the plain SQL for this query might be something like:

SELECT * FROM Customer WHERE CustomerID IN (
   SELECT CustomerID FROM Order WHERE OrderDate > '01-01-2012'
)

I can't figure out how to do this in EntityFramework.

I started with the following code, but can't figure out where to go from here.

var customersWithOrdersAfterGivenDate = this._dbContext.Customer
   .Include("Order")
   .Where(c => ??? What do I do here ??? );

I tried to do (c.Order.OrderDate > someDate), but this doesn't work because I can't get the OrderDate property from Order since EntityFramework is treating Order as a collection.

The second problem is: Get the total number of orders for a given collection or Customers

The plain SQL for this query might look like:

SELECT CustomerID, COUNT(*)
FROM Order
WHERE CustomerID IN (*someCollectionOfIDs*)
GROUP BY CustomerID

Again, I have no idea how to do this in EntityFramework. How do I get only the CustomerID and the total count of records for the CustomerID from the Order table? I can't figure out how to do a group by so that it doesn't just return every single order record for each customer.

----------------------------------


Update: Here's my final code after feedback from Eli.

To get Customers with Orders that were created after a given date:

var customerIDs = dbContext.Customer
   .Include("Order")
   .Where(c => c.Order.Any(o => o.DateCreated.CompareTo(startDate) > 0))
   .Select(s => new
      {
         c.CustomerID
      })
   .AsEnumerable()
   .Select(cust => cust.CustomerID)
   .ToList<int>();

To get total count of Orders for each Customer in a given collection of Customers:

List<int> customerIDs = GetCustomerIDsToQuery();

var orderTotals = dbContext.Orders
   .Where(o => customerIDs.Contains(o.CustomerID))
   .GroupBy(o => o.CustomerID)
   .Select(o => new
      {
         CustomerID = o.Key,
         TotalOrders = o.Count()
      })
   .AsEnumerable();

From the above, I can iterate through the collection and get the values from the anonymous type:

foreach(var ot in orderTotals)
{
   var customerID = ot.CustomerID;
   var totalOrders = ot.TotalOrders;
   //Do something with these values...
}
Was it helpful?

Solution

Your SQL also contains a nested collection, so your LINQ will be the same. Something along the lines of .Where(c => c.Orders.Any(order => order.OrderDate > someDate));

OTHER TIPS

int noOfRecords = _dbContext.Customer.Count();

this will return the number of records in a table in Entity framework.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top