EF6 query with Max and filters - entity-framework

In C# code with EF6 and Sql Server, my goal is to use this query :
Select MAX(columnA) from myTable WHERE columnB>5 AND ColumnC=1
by using C# code.
Example :
SELECT Max(ColumnA) from myTable
becomes :
int max = DbContext.myTable.Max(t => t.ColumnA); => works fine, OK
But do you know how to add the where clause into this C# code ???
Erixx

You put Where first and then Max later like this
int max = DbContext.myTable.Where(it=>it.columnB>5 && it.ColumnC=1).Max(t => t.ColumnA);

Just add the Where before Max (or after, depending on your logic).
int max = DbContext.myTable.Where(t => t.ColumnB > 5 && ColumnC == 1).Max(t => t.ColumnA)

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)

How to summarize DateTime-fields in EF6

again, I'm struggeling with Linq or EF6.
I have a table with columns (DateTime)[BeginOfWork] and (DateTime)[EndOfWork].
Now, I need to substract the BeginOfWork-value from the EndOfWork-value. From this result, I need to build a total sum.
In SQL, it looks like this:
SELECT Timesheets.EmployeeId, Sum(DateDiff("h",[Timesheets].[BeginOfWork],[Timesheets].[EndOfWork])) AS HoursOfWork
FROM Timesheets
GROUP BY Timesheets.EmployeeId
HAVING (((Timesheets.EmployeeId)=1));
How do I do this in EF6?
Actually, not working some variations of that:
int employeeId = 1;
var timesheetSum = (from ts in db.Timesheets
where (ts.EmployeeId == employeeId)
select new
{
hoursOfWork = DbFunctions.DiffHours(ts.BeginOfWork, ts.EndOfWork)
}).Sum(ts => ts.hoursOfWork);
The above results in integer rounded hoursOfWork, that don't include minutes.
So I tried that:
var timesheetSum = (from ts in db.Timesheets
where (ts.EmployeeId == employeeId)
select new
{
hoursOfWork = DbFunctions.DiffMinutes(ts.BeginOfWork, ts.EndOfWork) / 60
}).Sum(ts => ts.hoursOfWork);
But here, hoursOfWork seems to be rounded (integer), so 2,5 hours will result in 2. Perhaps a conversion of the result would work but I don't get it run.
`(double)hoursOfWork` results in an error.
Perhaps someone has a link to a complete guide, how to convert SQL to Linq-queries.
SOLUTION
var timesheetSum = (from ts in db.Timesheets
where (ts.EmployeeId == employeeId && ts.TimesheetDate <= DateTime.Today)
select new
{
hoursOfWork = DbFunctions.DiffMinutes(ts.BeginOfWork, ts.EndOfWork)/60m
}).Sum(ts => ts.hoursOfWork);
decimal result = 0;
if(timesheetSum!=null)
result = (decimal)timesheetSum;
Thanks a lot
Carsten

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.

EF 6.0 Get by datetime

I want to read from the table by datetime. If I use this:
(from x in Db.Table where x.Date.Value == DateTime.Now select x).ToList();
my code throws EntityCommandExecutionException:
A failure occurred while giving parameter information to OLE DB
provider
So I use this:
(from x in Db.Table where DbFunctions.TruncateTime(x.Date) == DateTime.Now select x).ToList();
but it is very slowly (about 40 seconds). In my table is approximately 500 000 records.
Thanks for advice
define now property first and then query like following:
var now = DateTime.Now;
var list = Db.Table.Where(e=>e.Date == now).ToList();
Or:
(from x in Db.Table where x.Date == now select x).ToList();

How do I make this Query against EF Efficient?

Using EF4. Assume I have this:
IQueryable<ParentEntity> qry = myRepository.GetParentEntities();
Int32 n = 1;
What I want to do is this, but EF can't compare against null.
qry.Where( parent => parent.Children.Where( child => child.IntCol == n ) != null )
What works is this, but the SQL it produces (as you would imagine) is pretty inefficient:
qry.Where( parent => parent.Children.Where( child => child.IntCol == n ).FirstOrDefault().IntCol == n )
How can I do something like the first comparison to null that won't be generating nested queries and so forth?
Try this:
qry.Where( parent => parent.Children.Any( child => child.IntCol == n ));
Any in Linq translates to exists in sql.
If I understood Your queries correctly, this is what You need.