Entity Framework Return Parent along with child entity as Ieunmerable List - entity-framework

I am new to Entity Framework and had a question i have been stuck on for a while. I have a repository in my DAL to access the data its returning IEnumerable lists for functions defined there. There are two tables involved here table Company and thier Customer_orders please see below for details. I need to return an Ienumerable list for Customer Orders ...which also includes the Customer name. I am able to return everything back for the customer order table but cant get the Customer name from the related table. Is it because I am returning a list of Ienumerable CustomerOrder type? If anyone can provide some help by showing the right code it would be greatly appreciated. Once again I am trying to bind to a grid pulling from the CustomerOrders table but need to also display CustomerName from Customers table.
Table1 (Customers)
company_id
customer_id
customerName
customerAddress
Table 2 (CustomerOrders)
customer_id
product_id
productName
productDesc
This is what I have so far this doesnt pull up any customer Names but pulls the CustomerOrders information
public IEnumerable<CustomerOrders> GetCustomerOrders(int company_id)
{
return context.Customers.Where(c => c.company_id == company_id).First().CustomerOrders.ToList().OrderBy(p => p.ProductName);
}

How about:
return context.CustomerOrders
.Include(o => o.Customer)
.Where(o => o.customer_id == customer_id);

Related

C# EF query for typical products - category relationship?

Using entity framework, trying to get some help for a query (prefer method based syntax) for this typical use case:
There is a products table, like:
ownerId
productId
ProductCategoryId
productInfo, etc.
There is a typical product-category-mapping table, like:
somePrimaryKey
ownerId
categoryId
productId
sortOrder
This set up allows one product to be in multiple category, and has its own sort order in each category. Also, we have the "ownerId" in all tables since each owner can only see his own data.
Now, given a categtoryId and ownerId, we need to find all products of this category, sorted by the sortOrder.
Any way how we should write this?
Many Thanks!
You can try to use something along those lines :
// Instanciate your context.
// Do it the way you've already done it, it's here only for example.
DbContext bd = new DbContext();
// The query :
List<Products> listProducts = new List<Products>();
listProducts = db.Products.Where(p => (db.ProductsCategories.Where(pc => pc.CategoryID == categoryID && pc.OwnerID == ownerID).Select(pc => pc.ProductID).OrderBy(pr => pr.sortOrder).ToList()).Contains(p.ProductID)).ToList();
This way use the product-category mapping (categorieID and ownerID are the datas you inject and you keep the sorting.

How to filter records using group functionality in BreezeJs

I'm developing a client app that uses breezejs and Entity Framework 6 on the back end. I've got a statement like this:
var country = 'Mexico';
var customers = EntityQuery.from('customers')
.where('country', '==', country)
.expand('order')
I want to use There may be hundreds of orders that each customer has made. For the purposes of performance, I only want to retrieve the latest order for each customer. This will be based on the created date for the order. In SQL, I could write something like this:
SELECT c.customerId, companyName, ContactName, City, Country, max(o.OrderDate) as LatestOrder FROM Customers c
inner join Orders o on c.CustomerID = o.CustomerID
group by c.customerId, companyName, ContactName, City, Country
If this was run against the northwind database, only the most recent order row is returned for each customer.
How can I write a similar query in breeze, so that it runs on the server side and therefore returns less data to the client. I know I could handle this all on the client but writing some javascript in a querysucceeded method that could be run by the client - but that's not the goal here.
thanks
For a case like this, you should create a special endpoint method that will perform your query.
Then you can use an Entity Framework query to do what you want, using the LINQ syntax.
Here are two Web API examples:
[HttpGet]
public IQueryable<Object> CustomersLatestOrderEntities()
{
// IQueryable<Object> containing Customer and Order entity
var entities = ContextProvider.Context.Customers.Select(c => new { Customer = c, LatestOrder = c.Orders.OrderByDescending(o => o.OrderDate).FirstOrDefault() });
return entities;
}
[HttpGet]
public IQueryable<Object> CustomersLatestOrderProjections()
{
// IQueryable<Object> containing Customer and Order entity
var entities = ContextProvider.Context.Customers.Select(c => new { Customer = c, LatestOrder = c.Orders.OrderByDescending(o => o.OrderDate).FirstOrDefault() });
// IQueryable<Object> containing just data fields, no entities
var projections = entities.Select(e => new { e.Customer.CustomerID, e.Customer.ContactName, e.LatestOrder.OrderDate });
return projections;
}
Note that you have a choice here. You can return actual entities, or you can return just some data fields. Which is right for you depends upon how you are going to use them on the client. If they are just for display in a
non-editable list, you can just return the plain data (CustomersLatestOrderProjections above). If they can potentially
be edited, then return the object containing the entities (CustomersLatestOrderEntities). Breeze will merge the entities
into its cache, even though they are contained inside this anonymous object.
Either way, because it returns IQueryable, you can use the Breeze filtering syntax from the client to further qualify the query.
var projectionQuery = breeze.EntityQuery.from("CustomersLatestOrderProjections")
.skip(20)
.take(10);
var entityQuery = breeze.EntityQuery.from("CustomersLatestOrderEntities")
.where('customer.countryName', 'startsWith', 'C');
.take(10);

Using Inner joins in Entity Framework on multiple tables?

I have a student table in my database with columns Id, Name, DepartmentId, CollegeId, CityId etc and a Department table, College table to map to the DepartmentId, CollegeId in the Student table.
Now I want to pass CityId and retrieve Id, Name, DepartmentName, CollegeName with help of the corresponding tables using inner join based on the CityId.
I'm implementing a method FindAll() which takes in CityId as the input parameter and retrieves data based on CityId
public IEnumerable<StudentRegionEntity> FindAll(int CityId)
{
var totalStudents = new List<StudentRegionEntity>();
foreach(var entity in this.Dbcontext.Students)
{
}
}
In the foreach loop I want to bind the list of students with Id, Name, Department, College fields, how can I use joins and implement the functionality for FindAll()?
var studentEntities = this.Dbcontext.Students
.Include("StudentList").Where(s => s.cityId == CityId).ToList()
this will give the list of all the StudentEntity entities with StudentRegionEntity attached, using one join query to the database.

Entity Framework Conditional Count of Navigation Property 2 levels down

Just starting out with Entity Framework and am trying to work out how you would do something like this....
Say I have the following entities, Customers that have Orders that have OrderLineItems which are linked to Products. I would like to return the name of every customer with a count of the number of times they have ordered a particular product.
I have seen examples of using .Count() but these have always been for the first navigation property i.e. number of orders per customer.
Would appreciate some guidance here.
Something like this should work, where context is your DbContext instance.
It will return an IEnumerable<dynamic>, although obviously you could make a class to hold the results.
// The product to count
var productId = 12345;
context.Customers.Include("Orders.OrderLineItems.Products")
.Select(customer =>
new {
CustomerName = customer.Name,
ProductCount = customer.Orders
.SelectMany(o => o.OrderLineItems)
.SelectMany(i => i.Products.Where(p => p.Id = productId).Count()
});
The Include() extension method is useful, it will make sure that the resulting SQL query joins the relevant tables together - otherwise multiple queries would be executed for each customer (one to get orders, another for line items and a final one for products).

Breeze with stored procedure CLR error

Im trying to call a stored procedure using Entity framework.
If I go direcly to the web api method it works fine, but when calling it from breeze it causes an exception on the metadata method.
The error is :
"Could not find the CLR type for...".
Anyone know how to fix this?
I had the very same issue, but thank God I figured out a solution. Instead of using a stored procedure, you should use a view, as Breeze recognizes views as DbSet<T>, just like tables. Say you have a SQL server table that contains two tables Customers and Orders.
Customers (**CustomerId**, FirstName, LastName)
Orders (OrderId, #CustomerId, OrderDate, OrderTotal)
Now, say you want a query that returns orders by CustomerId. Usually, you would do that in a stored procedure, but as I said, you need to use a view instead. So the query will look like this in the view.
Select o.OrderId, c.CustomerId, o.OrderDate, o.OrderTotal
from dbo.Orders o inner join dbo.Customers c on c.CustomerId = o.CustomerId
Notice there is no filtering (where ...). So:
i. Create a [general] view that includes the filtering key(s) and name it, say, OrdersByCustomers
ii. Add the OrdersByCustomers view to the entity model in your VS project
iii. Add the entity to the Breeze controller, as such:
public IQueryable<OrdersByCustomers> OrdersByCustomerId(int id)
{
return _contextProvider.Context.OrdersByCustomers
.Where(r => r.CustomerId == id);
}
Notice the .Where(r => r.CustomerId == id) filter. We could do it in the data service file, but because we want the user to see only his personal data, we need to filter from the server so it only returns his data.
iv. Now, that the entity is set in the controller, you may invoke it in the data service file, as such:
var getOrdersByCustomerId = function(orderObservable, id)
{
var query = breeze.EntityQuery.from('OrdersByCustomerId')
.WithParameters({ CustomerId: id });
return manager.executeQuery(query)
.then(function(data) {
if (orderObservable) orderObservable(data.results);
}
.fail(function(e) {
logError('Retrieve Data Failed');
}
}
v. You probably know what to do next from here.
Hope it helps.