I am converting SQL queries to slick DSL. I am stuck in timestamp conversion.
My SQL query is:
Select isActive from users where create_time <= TIMESTAMPADD(MINUTE,
${AUTO_EXPIRY_DB_DAYS * HOURS_24 * MINUTES_60}, sysdate())
and isVerified=false;
How to write a slick query for the same?
userQuery.filter(user => user.isVerified === FALSE && user.createdDate
<= ?????).map(_.isActive)
Take a look at scalar database functions slick documentation. I suppose this should work:
val sysdate = SimpleLiteral[java.sql.Timestamp]("sysdate")
val timestampAdd = SimpleFunction.ternary[String, Int, java.sql.Timestamp, java.sql.Timestamp]("TIMESTAMPADD")
userQuery
.filter(user => user.isVerified === FALSE
&& user.createdDate <= timestampAdd("MINUTE", 20, sysdate))
.map(_.isActive)
Related
I've got a strange situation.
I've got a column (smallint) that has a single value of 6
I run using a linq to retrieve records that are Validity_months old.
var query = db.table_1
.AsNoTracking()
.Include(b => b.table_2)
.ThenInclude(t => t.table_3)
.Where(e => e.Date <= DateTime.UtcNow.AddMonths(e.table_2.ValidityMonths))
.Where(e => e.Date >= DateTime.UtcNow.AddMonths(e.table_2.ValidityMonths*-1)));
This throws an MySQL Error
Error Code: 1690. BIGINT UNSIGNED value is out of range in '(database.s0.validity_months * (-(1)))'
The query above translates into SQL Query
SELECT *
FROM `table_1` AS `s`
LEFT JOIN `table_2` AS `s0` ON `s`.`table_2_id` = `s0`.`id`
LEFT JOIN `table_3` AS `s1` ON `s0`.`table_3_id` = `s1`.`id`
WHERE (`s`.`date` <= DATE_ADD(UTC_TIMESTAMP(), INTERVAL CAST(`s0`.`validity_months` AS signed) month)))
AND (`s`.`date` >= DATE_ADD(UTC_TIMESTAMP(), INTERVAL CAST(`s0`.`validity_months` * -1 AS signed) month));
This ran into MySQL throws the same error. The problem is at
CAST(`s0`.`validity_months` * -1 AS signed)
How do I negate a field in LINQ. This feels like it's a EFCore bug, but I am not sure yet.
I have a web app built in .NETCore 2.1 which calls an API built in .Net 4.6. The API calls a services layer which is using entity framework 6. I'm connecting to a MySql database. I'm using the Pomelo.EntityFrameworkCore.MySql connector. When using a LINQ query to get records based on a date comparison, EF6 appears to be cmparing the dates as string literals.
I've tried all different types of variations of the LINQ query and looked online for extension libraries that do date comparisons, but to no avail
Here's the LINQ query
int year = DateTime.Now.Year;
DateTime firstDayOfYear = new DateTime(year, 1, 1);
DateTime lastDayOfYear = new DateTime(year, 12, 31);
var startDate = firstDayOfYear.AddYears(-2);
var endDate = lastDayOfYear.AddYears(-1);
var company = dbContext.Companies.Where(c =>
c.Updating &&
c.UpdatedBy == username &&
c.LastUpdate > startDate &&
c.LastUpdate < endDate)
.FirstOrDefault();
Here's part of the SQL that is generated. note the # symbols before the date values
`Extent2`.`ID` AS `ID1`,
`Extent2`.`Name` AS `Name1`
FROM Company AS `Extent1` INNER JOIN `Table_2` AS `Extent2` ON `Extent1`.`ID` = `Extent2`.`ID`
WHERE ((((`Extent1`.`SomeFlag` != 1) AND (`Extent1`.`LastUpdate` > #'01/01/2017 00:00:00')) AND (`Extent1`.`LastUpdate` < #'31/12/2017 00:00:00')) AND ((`Extent1`.`ID` IN ( '1','2','6','7','8' )) AND (`Extent1`.`ID` IS NOT NULL))) AND (NOT ((`Extent1`.`Telephone` IS NULL) OR ((LENGTH(`Extent1`.`Telephone`)) = 0)))) AS `Project1`
Running the sql query manually in MySql workbench returns no rows. if I remove the # symbols it does return rows, as expected. What am I doing wrong?
I couldn't figure out why EF was translating the LINQ that way so I just used a stored procedure call to get round it. At least then I could write the SQL myself.
int year = DateTime.Now.Year;
DateTime firstDayOfYear = new DateTime(year, 1, 1);
DateTime lastDayOfYear = new DateTime(year, 12, 31);
var startDate = firstDayOfYear.AddYears(QueueConfig.UpdateQueueStartDateInYears);
var endDate = lastDayOfYear.AddYears(QueueConfig.UpdateQueueStartDateInYears);
var userParam = new MySql.Data.MySqlClient.MySqlParameter("userName", username);
var sdParam = new MySql.Data.MySqlClient.MySqlParameter("startDate", startDate);
var edParam = new MySql.Data.MySqlClient.MySqlParameter("endDate", endDate);
var lockedCompany = dbContext.Database.SqlQuery<CompanyDto>("CALL GetLockedCompany(#userName,#startDate,#endDate)", userParam, sdParam, edParam);
var companyDto = lockedCompany.SingleOrDefault();
I'm trying to execute the following query using knex.js and MySql
SELECT
m.id,
TIME(date_created) AS `timestamp`,
u.username,
m.`message`
FROM
`messages` AS m
INNER JOIN users AS u ON u.id = m.user_id
WHERE
m.game_id IS NULL
AND m.`date_created` > DATE_SUB(
CURRENT_TIMESTAMP (),
INTERVAL 12 HOUR
)
ORDER BY
m.`date_created` ASC
LIMIT 50
For proper handling expressions in where closure such as DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR) according to documentation there is whereRow() method in knex.
I tried to use select() method as
select('messages.id', 'TIME(date_created) AS timestamp', 'users.username', 'messages.message')
But knex masks TIME(date_created) expression in a way it should to be a column name. Does anybody know a way to use a custom expressions in selects?
I did not found exact answer on my question but I've found a solution which allows me to move forward. I created separate model which uses standard Bookshelf(knex) export:
var Bookshelf = require('bookshelf')(knex);
module.exports.DB = Bookshelf;
And created separate method in that model where I could use DB.knex.raw() for masking DB expressions in SELECT. So I became able to write the query above in the following way:
var DB = require('./../db').DB;
var Messages = DB.Model.extend({
tableName: 'messages',
hasTimestamps: false,
idAttribute: 'id'
},
{
getMessagesHistory: function (gameId) {
return this.query().select('messages.id', DB.knex.raw('TIME(date_created) AS timestamp'), 'users.username', 'messages.message')
.innerJoin('users', 'messages.user_id', 'users.id')
.whereRaw("messages.game_id " + (gameId == 0 ? "IS NULL" : "= " + gameId))
.andWhereRaw("messages.date_created > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)")
.orderBy('messages.date_created', 'ASC')
.limit(50);
}
}
);
module.exports = Messages;
You can wrap any argument with knex.raw() to tell the framework that it's a raw piece of SQL:
select(
'messages.id',
knex.raw('TIME(date_created) AS timestamp'),
'users.username',
'messages.message',
)
See http://knexjs.org/#Raw-Bindings
select *
from qmsCallAudit
where CAST(FLOOR(CAST(callauditdt AS float)) AS DATETIME)
between '2015-07-16 00:00:00' and '2015-07-16 00:00:00'
above query return records in sql query
from linq its not not working, below is application code
var query = (
from qd in db.qmsCallAuditDetails
from qm in db.qmsCallAudits
where qm.callaudit_id == qd.callaudit_id &&
qm.active == true
&& qm.process_id == processid
&& fdt >= qm.callauditdt
&& tdt <= qm.callauditdt
select qd
).AsQueryable();
string semp = frm["employee_id"];
if (semp.Length > 0)
{
int empid = Convert.ToInt32(frm["employee_id"]);
query = query.Where(q => q.qmsCallAudit.employee_id==empid);
}
below sql profile code for above linq query
exec sp_executesql N'SELECT
[Extent1].[callauditdetail_id] AS [callauditdetail_id],
[Extent1].[callaudit_id] AS [callaudit_id],
[Extent1].[subparameter_id] AS [subparameter_id],
[Extent1].[subparameterdisp_id] AS [subparameterdisp_id],
[Extent1].[score] AS [score],
[Extent1].[weightage] AS [weightage],
[Extent1].[fatal] AS [fatal],
[Extent1].[add_to_weightage] AS [add_to_weightage],
[Extent1].[auditstatus] AS [auditstatus],
[Extent1].[auditscore] AS [auditscore],
[Extent1].[auditweightage] AS [auditweightage],
[Extent1].[auditremark] AS [auditremark],
[Extent1].[createdon] AS [createdon],
[Extent1].[createdby] AS [createdby],
[Extent1].[modifiedon] AS [modifiedon],
[Extent1].[modifiedby] AS [modifiedby],
[Extent1].[active] AS [active]
FROM [dbo].[qmsCallAuditDetail] AS [Extent1]
INNER JOIN [dbo].[qmsCallAudit] AS [Extent2] ON [Extent2].[callaudit_id] = [Extent1].[callaudit_id]
WHERE (1 = [Extent2].[active]) AND ([Extent2].[process_id] = #p__linq__0) AND (#p__linq__1 >= [Extent2].CAST(FLOOR(CAST(callauditdt AS float)))[callauditdt]) AND (#p__linq__2 <= [Extent2].[callauditdt])',N'#p__linq__0 int,#p__linq__1 datetime2(7),#p__linq__2 datetime2(7)',#p__linq__0=2,#p__linq__1='2015-07-16 00:00:00',#p__linq__2='2015-07-16 00:00:00'
Whats your error? Are your ftd and tdt already dateTime objects?
I'm trying to figure out how to write a linq query that will return equivalent results to the sql query below. The problem I'm having has to do with the two select count queries included in the select list of the main query. I need to get counts of two different types of records from the PaymentHistory table for the last year. Can the equivalent of this be written using linq? Preferrably using lambda syntax.
select ieinum, serviceaddrkey,
(select count(*) from PaymentHistory where serviceaddrid = serviceaddrkey
and PostDate >= DateAdd(year, -1 , GetDate())
and SetID = 100) as ReturnedFees,
(select count(*) from PaymentHistory where serviceaddrid = serviceaddrkey
and PostDate >= DateAdd(year, -1 , GetDate())
and SetID = 101) as CorrectedReturnedFees
from Serviceaddr
Any help will be great.
Perhaps something like this:
from s in Serviceaddr
let ph = PaymentHistory.Where(p => s.serviceaddrkey == p.serviceaddrkey &&
p.PostDate >= DateTime.Now.AddYears(-1))
select new
{
s.ieinum,
s.serviceaddrkey,
ReturnedFees = ph.Count(p => p.SetID == 100),
CorrectedReturnedFees = ph.Count(p => p.SetID == 101)
}