LINQ - How to select with subquery - linq

My data is:
+-----+--------+-----------+
| Id | Name | ParentId |
+-----+--------+-----------+
| 1 | A | 0 |
| 2 | B | 0 |
| 3 | C | 1 |
+-----+--------+-----------+
How do I get C if we have ParentId = 0 by LINQ?

Assuming "Categories" is the collection name, I think this is what you need.
var parentCategoryIds = Collections.Where(c => c.ParentId == 0).Select(c => c.Id);
var results = Collections.Where(c => parentCategoryIds.Contains(c.ParentId));
And if you want to get the name, you can do
var names = results.Select(r => r.Name);
These three statements could be written into one linq statement but I did this for clarity.

Related

How to get all unique records with the maximum value in column using LINQ

Learner | AssesmentId | Attempt
------------------------------------
Parker | 1 | 1
Parker | 1 | 2
Stark | 1 | 1
Rogers | 1 | 1
Rogers | 1 | 2
Parker | 1 | 3
Given this data, how do I get all the unique Student name with the highest Attempt?
I'm attempting to get this result:
Learner | AssesmentId | Attempt
------------------------------------
Parker | 1 | 3
Stark | 1 | 1
Rogers | 1 | 2
How can I do this in a single query in LINQ?
from la in _context.LearnerAssessments
where la.AssessmentId == assessmentId
&& learnerIds.Contains(la.LearnerId)
&& la.Attempt == {highest attempt}
var data = from list in _context.LearnerAssessments
group list by new
{
list.Learner,
list.AssesmentId
}
into g
select new
{
g.Key.Learner,
g.Key.AssesmentId,
Max= g.Max(x=>x.Attempt)
};
or using fluent API :
var data = _context.LearnerAssessments.GroupBy(l => new { l.Learner, l.AssesmentId }, (keys, item) => new
{
Key = keys,
MaxAttemp = item.Max(x => x.Attempt)
}).Select(x => new LearnerAssessment
{
Learner = x.Key.Learner,
Attempt = x.MaxAttemp,
AssesmentId = x.Key.AssesmentId
});

How Products is order by relation in Laravel?

How can I sort the products in table1 according to their connection with table2 i.e. sort the products in table1 by example_relation in table2?
Table1
| id | product |
|----|---------|
| 1 | pro1 |
| 2 | pro2 |
| 3 | pro3 |
| 4 | pro4 |
| 5 | pro5 |
Table2
| id | example_relation | product_id |
|----|------------------|------------|
| 1 | 700 | 1 |
| 2 | 800 | 2 |
| 3 | 900 | 3 |
| 4 | 850 | 2 |
| 5 | 600 | 4 |
| 6 | 125 | 5 |
Table1 model page:
public $belongsTo = [
'pro_relation' => [
'models\Model',
'key' => 'id',
'otherKey' => 'product_id',
],
Sorting section that needs to be arranged correctly:
$query->whereHas('pro_relation', function($q) use ($postFrom,$postTo){
$q->select('example_relation END AS expose');
})->orderBy("expose", DESC);
Okay, when you want to order the result of one table from another table then you can use orderBy() inside a closure of the relationship to another table.
So from your query, you can add orderBy() like so.
$query->whereHas('pro_relation', function($q) use ($postFrom,$postTo){
$q->select('example_relation END AS expose')
->orderBy('example_relation');
});
This is work
$query->join('table2', 'table1.id', '=', 'table2.yacht_id')
->orderBy(example_relation DESC);

How can I get a post with all related ones?

Here is my table structures:
// tickets
+----+------------+----------------------+--------+---------+
| id | subject | content | closed | user_id |
+----+------------+----------------------+--------+---------+
| 1 | subject1 | question1 | 0 | 123 |
+----+------------+----------------------+--------+---------+
// answers
+----+----------------------+---------+-----------+
| id | content | user_id | ticket_id |
+----+----------------------+---------+-----------+
| 1 | answer1 | 123 | 1 |
| 2 | answer2 | 456 | 1 |
+----+----------------------+---------+-----------+
Now I need to get a ticket with along all its answers. I can do that using pure SQL like this:
SELECT t.*, a.*
FROM tickets t
LEFT JOIN answers a
ON t.id = a.ticket_id
WHERE t.id = ?
Now I'm using Laravel and I want to do that using with() class (however not sure it is possible). Any idea what change should I make in the models for doing that?
Noted that I can get just a ticket in Laravel like this:
$ticket = Tickets::where('id', $request->id)->get();
First make a hasMany() relationship in your Tickets model class.
public function answers()
{
return $this->hasMany(Answers::class, 'ticket_id', 'id');
}
And then in your controller query
$tickets = Tickets::with('answers')->where('id', $request->id)->get();

Multiple Tables Group and substract sum of columns using linq sql

Here i have two tables
Table One
+---------------+----------+------------+
| Raw Material | Size | Qty |
+---------------+----------+------------+
| A | 1 | 5 |
| A | 2 | 2 |
| A | 1 | 2 |
| B | 0 | 5 |
| B | 0 | 1 |
+---------------+----------+------------+
Table Two
+---------------+----------+------------+
| Raw Material | Size | Qty |
+---------------+----------+------------+
| A | 1 | 2 |
| A | 2 | 1 |
| A | 1 | 1 |
+---------------+----------+------------+
I want out put like
+---------------+----------+------------+
| Raw Material | Size | Qty |
+---------------+----------+------------+
| A | 1 | 4 |
| A | 2 | 1 |
| B | 0 | 6 |
+---------------+----------+------------+
Want to get substract first two tables sum of qty by grouping Rawmaterial and Size
Something like this should do the job
var result = tableA.Select(e => new { Item = e, Factor = 1 })
.Concat(tableB.Select(e => new { Item = e, Factor = -1 }))
.GroupBy(e => new { e.Item.RawMaterial, e.Item.Size }, (key, elements) => new
{
RawMaterial = key.RawMaterial,
Size = key.Size,
Qty = elements.Sum(e => e.Item.Qty * e.Factor)
}).ToList();
First we create a union of the two tables using Concat, including the information which one is additive (in Factor field), and then just do the normal grouping.
If you want the result to be List<YourTableElementType>, just replace the final anonymous type projection (new { ... }) with new YourTableElementType { ... }.

Best Practice for retrieving and iterating over one to many

I'm trying to produce a web page report of Orders Per Customer with line item details for each order.
So it looks like this:
Customer 1 | Order 1 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
| | == New Row == |
| ====== New Row ========= |
| Order 2 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
| | == New Row == |
| ====== New Row ========= |
| Order 3 | Item 1 |
| | Item 2 |
== New Row ==============================
Customer 2 | Order 1 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
| | == New Row == |
| | Item 4 |
| | == New Row == |
| | Item 5 |
| | == New Row == |
| ====== New Row ========= |
| Order 2 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
== New Row ==============================
Is it better to get an array list of data as follows:
1 | 1 | 1 |
1 | 1 | 2 |
1 | 1 | 3 |
1 | 2 | 1 |
1 | 2 | 2 |
1 | 2 | 3 |
1 | 3 | 1 |
1 | 3 | 2 |
2 | 1 | 1 |
2 | 1 | 2 |
2 | 1 | 3 |
2 | 1 | 4 |
2 | 1 | 5 |
2 | 2 | 1 |
2 | 2 | 2 |
2 | 2 | 3 |
and pass 1 JavaBean and use JSTL to determine the nesting as follows:
this is incomplete for brevity
<table><tr><th>Customer No</th><th>Orders</th></tr>
<c:forEach var="custOrderLineItem" items="${customerOrderLineItemList}">
<c:set var="currentOrder" value="custOrderLineItem.orderId">
<c:set var="currentCustomer" value="custOrderLineItem.customerId">
<c:if test="${currentOrder != custOrderLineItem.orderId}">
==New Row==
</c:if>
or is it better to use nested JavaBeans
Customer.setOrders<List>
Orders.setOrderDetails<List>
OrderDetails.setLineItem<List>
and then use JSTL as such
<c:forEach var="customer" items="${customerList}">
<c:forEach var="order" items="${customer.orderList}">
<c:forEach var="lineItem" items="${order.detailList}">
After spending the time writing this, I feel like the second method looks cleaner and easier. But the first method seems to have an easier SQL query. I'm not using JPA, just basic JDBC sql calls. So how does one populate nested JavaBeans, without JPA? Do you do something like this?
List<Customer> custList = getCustomerList();
ListIterator custListIter = custList.listIterator();
while (custListIter.hasNext()) {
customer = (Customer) custListIter.next();
List<Order> orderList = getOrderList(customer.getId());
ListIterator orderListIter = orderList.listIterator();
while (orderListIter.hasNext()) {
order = (Order) orderListIter.next();
List orderDetailsList<OrderDetail> = getOrderDetailList(order.getId);
order.setOrderDetails(orderDetailsList);
orderListIter.set(order);
}
customer.setOrderList(orderList);
custListIter.set(customer);
}
You could simply make the SQL query which returns everything, and build the graph of objects from the result set. Using maps to keep an association between IDs and the corresponding objects:
Map<Long, Customer> customersById = new HashMap<Long, Customer>();
Map<Long, Order> ordersById = new HashMap<Long, Order>();
Map<Long, Item> itemsById = new HashMap<Long, Item>();
while (rs.next()) {
Long customerId = rs.getLong(1);
Customer customer = customersById.get(customerId);
if (customer == null) {
customer = new Customer(customerId);
// populate other fields of customer
customersById.put(customerId, customer);
}
Long orderId = rs.getLong(5);
Order order = ordersById.get(orderId);
if (order == null) {
order = new Order(orderId);
customer.addOrder(order);
// populate other fields of order
ordersById.put(orderId, order);
}
// same for items
}
At the end of the loop, you have all the customers, each with their orders, each with their items.

Resources