Cakephp 3 find('list') - find

I wanted to prefill a multiple Checkbox form with Data from MySql Database.
My Database Data :
id customer_id language_id preferred
1 10 150 yes
2 10 149 yes
The query in Controller "Preferredcustomerlanguages"
$clientlanguages = $this->Preferredcustomerlanguages
->find('list')
->select(['language_id'])
->where(['customer_id =' => $customer_id])
->where(['preferred =' => 'yes'])
->toArray()
;
If i start the query with $customer_id = 10 the result is this:
[
(int) 2 => (int) 2,
(int) 1 => (int) 1
]
I thought the query would give me a list of the language_id which i need to prefill my form.
Maybe someone can give me a hint where iḿ thinking wrong

If you want to select a field different to displayField, you can use the list arguments for this:
$clientlanguages = $this->Preferredcustomerlanguages
->find('list', [
'keyField' => 'id',
'valueField' => 'language_id'
])
->where(['customer_id =' => $customer_id])
->where(['preferred =' => 'yes'])
->toArray();
https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#finding-key-value-pairs

Related

Easiest way to delete all records except the last 10 by date using EFCore [duplicate]

Let's say that I have a table like:
Id Name Category CreatedDate
1 test test 10-10-2015
2 test1 test1 10-10-2015
...
Now, I would like to delete all rows and leave only the top 10 from all categories (by top 10 I mean the 10 newest according to createdDate).
Using raw SQL, it would be like:
DELETE FROM [Product]
WHERE id NOT IN
(
SELECT id FROM
(
SELECT id, RANK() OVER(PARTITION BY Category ORDER BY createdDate DESC) num
FROM [Product]
) X
WHERE num <= 10
How is this done when using the DbContext in Entity Framework?
// GET all products
var list = ctx.Products.ToList();
// GROUP by category, ORDER by date descending, SKIP 10 rows by category
var groupByListToRemove = list.GroupBy(x => x.Category)
.Select(x => x.OrderByDescending(y => y.CreatedDate)
.Skip(10).ToList());
// SELECT all data to remove
var listToRemove = groupByListToRemove.SelectMany(x => x);
// Have fun!
ctx.Products.RemoveRange(listToRemove);
Guessing it will take a whil if you have a lot of data but.
var oldItems = efContext.Products
.GroupBy(x => x.Category,
(c,p) => p.OrderByDescending(x => p.createdDate).Skip(10))
.SelectMany(p => p);
efContext.Products.RemoveRange(oldItems);
Will do the trick
(Written in notepad)

Is there a way to use `COUNT(DISTINCT)` in EF Core 3.1?

I have a table with the following data
ID DateColumn Amount
1 2021-01-25 50
2 2021-01-24 10
1 2021-01-25 100
I need the following output,
ID DayCount TotalAmount
1 1 150
2 1 10
I'm trying to lambda expression that would generate the following SQL query,
select ID, Count(distinct DateColumn) as DayCount, Sum(Amount) as TotalAmount
from test
group by id
I've writte the following expression,
return await _context.Tests
.GroupBy(g => g.id)
.Select(s => new
{
Data = s.Key,
Count = s.Select(t => t.DateColumn).Distinct().Count()
}).ToListAsync();
and it throws the InValidOperation exception.
There seems to be an error in the resulting table for the first record, which should have a value of 2 for the DayCount.
The resting table construction looks like it could use some rearchitecting due to the Id column containing duplicates.
Regardless of structure, you can use an inner GROUP BY to achieve similar results:
return await _context.Tests
.GroupBy(g => g.id)
.Select(s => new
{
Data = s.Key,
Count = s.GroupBy(t => t.DateColumn).Select(g => g.key).Count()
})
.ToListAsync();

Cannot retrieve data from find query

In my Event model, I have the following function to retrieve all the events with status = 1 with a 12 limit and order according to event created DESC:
public function latestEvents() {
$this->Behaviors->load('Containable');
$result = $this->find('all' ,array('recursive' => -1, 'conditions'=> array('Event.status' => 1), 'limit' => 12, 'order' => array('Event.created DESC')));
debug($result); die();
return $result;
}
This function is not returning any data. When I change my limit to 6 and debug it returns six records but when I change my limit to more than 6 it returns (empty) this :
I even checked in my database by doing this query :
SELECT * FROM `events` WHERE `status` = 1 ORDER BY `created` DESC LIMIT 12
and this returns the desired data that I want. I even tried :
$result = $this->query('SELECT * FROM `events` WHERE `status` = 1 ORDER BY `created` DESC LIMIT 12');
but the same thing is happening with the limit (6 returns the data but more than 6 does not).
I found out that the data I was trying to debug had special characters and I had to include 'encoding' => 'utf8' in my database.php and worked like a charm. This post helped me.

Getting last row in mongodb

I am using find() function in mongodb and got a record in following format
Array
(
[_id] => MongoId Object
(
[$id] => 52a561ea78e9288b568b4567
)
[friendID] => 1
[name] => Shobhit Srivastav
[senderID] => 2
[receiverID] => 1386570218
[receiverType] => TW
[receiverUserID] => 3
[status] => 0
)
Array
(
[_id] => MongoId Object
(
[$id] => 52a5623178e928d8568b4567
)
[friendID] => 2
[name] => Sachin Tendulkar
[senderID] => 2
[receiverID] => 1386570289
[receiverType] => TW
[receiverUserID] => 3
[status] => 0
)
but I want record of last row which are inserted in the table. how can I find??
Thanks in advance!!
If you want to get last record inserted in the table, then sort by ObjectId in descending order:
sorting on an _id field that stores ObjectId values is roughly
equivalent to sorting by creation time.
and get first record:
db.collection.find().sort( { _id : -1 } ).limit(1);
With php driver it will look like
$doc = $collection->find()->sort(array("_id" => -1))->limit(1)->getNext();

EntityFramework Query select (contains) (all villages that have farmers which plant apples)

village(id, list(farmers))
farmer(id, List(fruits));
fruit(id,name).
How would I write a query that selects all villages that have the fruit with ID 23 (e.g. apples)?
It would be easy to write this with 2 queries. How wold you do it with one?
Try
var villages = db.Villages
.Where(v => v.Farmaers.Any(f => f.Fruits.Any(t => t.Id == 23)));