CurrentUtcDateTime does not exist - Entity Framework and MySql - mysql

I am having a problem with canonical functions in Entity Framework 4.1 and MySql Connector/Net 6.4.3.
According to Microsoft cannonical functions are understood and translated into the local SQL dialect by all database providers from the SQL generated by LINQ; http://msdn.microsoft.com/en-us/library/bb738626.aspx However, my code chokes on CurrentUtcDateTime(), which is listed here; http://msdn.microsoft.com/en-us/library/bb738563.aspx
Here is the LINQ query (from NopCommerce) that generates the offensive SQL:
public List<Poll> GetPolls(int languageId, int pollCount, bool loadShownOnHomePageOnly)
{
bool showHidden = NopContext.Current.IsAdmin;
var query = (IQueryable<Poll>)_context.Polls;
if (!showHidden)
{
query = query.Where(p => p.Published);
query = query.Where(p => !p.StartDate.HasValue || p.StartDate <= DateTime.UtcNow);
query = query.Where(p => !p.EndDate.HasValue || p.EndDate >= DateTime.UtcNow);
}
if (loadShownOnHomePageOnly)
{
query = query.Where(p => p.ShowOnHomePage);
}
if (languageId > 0)
{
query = query.Where(p => p.LanguageId == languageId);
}
query = query.OrderBy(p => p.DisplayOrder);
if (pollCount > 0)
{
query = query.Take(pollCount);
}
var polls = query.ToList();
return polls;
}
query.ToList() generates the SQL below:
SELECT`Project1`.`PollID`, `Project1`.`LanguageID`, `Project1`.`Name`,
`Project1`.`Published`, `Project1`.`ShowOnHomePage`, `Project1`.`DisplayOrder`,
`Project1`.`SystemKeyword`, `Project1`.`StartDate`, `Project1`.`EndDate`
FROM (SELECT`Extent1`.`PollID`, `Extent1`.`LanguageID`, `Extent1`.`Name`,
`Extent1`.`SystemKeyword`, `Extent1`.`Published`, `Extent1`.`ShowOnHomePage`,
`Extent1`.`DisplayOrder`, `Extent1`.`StartDate`, `Extent1`.`EndDate`
FROM `Nop_Poll` AS `Extent1` WHERE ((((`Extent1`.`Published` = 1) AND
((`Extent1`.`StartDate` IS NULL) OR (`Extent1`.`StartDate` <= (CurrentUtcDateTime()))))
AND ((`Extent1`.`EndDate` IS NULL) OR (`Extent1`.`EndDate` >= (CurrentUtcDateTime()))))
AND (`Extent1`.`ShowOnHomePage` = 1)) AND (`Extent1`.`LanguageID` = #p__linq__0))
AS `Project1` ORDER BY `Project1`.`DisplayOrder` ASC LIMIT 2147483647
This is error is outputed:
*FUNCTION myDatabase.CurrentUtcDateTime does not exist
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: MySql.Data.MySqlClient.MySqlException: FUNCTION myDatabase.CurrentUtcDateTime does not exist*
Am I missing something? Please advice. Thanks.

I encountered this exact same problem and lost almost two days trying to figure it out. It appears to be a bug in the EntityFramework mappings for MySql.
The solution is to move the DateTime.UtcNow calculation outside of the scoped lambda and plug in the actual value.
var utcNow = DateTime.UtcNow;
query = query.Where(p => p.Published);
query = query.Where(p => !p.StartDate.HasValue || p.StartDate <= utcNow);
query = query.Where(p => !p.EndDate.HasValue || p.EndDate >= utcNow);

Based on Bohemian's suggestion, I fixed this issue with a "bypass" function.
CREATE FUNCTION `your_schema`.`CurrentUtcDateTime` ()
RETURNS TIMESTAMP DETERMINISTIC
RETURN UTC_TIMESTAMP();

Use UTC_TIMESTAMP()

Related

How to pass in operators to SQL from NodeJS

In my NodeJS app, I want the user to be able to pass in a filter into a mySQL (v8.0.20) query (using Knex):
const sql = 'SELECT * FROM xyz WHERE id = ? AND ?? ? ?';
The series of question marks at the end is where I want to add in the filter, e.g. id > 3. I know one question mark indicates a value and two indicates an attribute/table name. But neither work for <,>,=. How do I tell SQL that this is a built-in operator?
You can't use parameters to supply structural parts of an SQL query. Parameters are meant to be value placeholders.
If you scrutinize the user-supplied field names and operators properly, you can build the SQL query dynamically. Keep the ? for user-supplied values.
const allowedOperators = ['=', '>', '>=', '<', '<=', '!='];
const allowedFields = ['id', 'name', 'etc'];
if (
allowedOperators.indexOf(userSuppliedOperator) > -1 &&
allowedFields.indexOf(userSuppliedField.toLowerCase()) > -1
) {
var sql = `SELECT * FROM xyz WHERE id = ? AND {userSuppliedField} {userSuppliedOperator} ?`;
// use SQL string
} else {
throw new Error("Invalid search parameters");
}

Query builder output for a report is undefined for a Google Cloud SQL DB but working out fine on ClearBD on Heroku

I am trying to generate a csv report which is later mailed to the recipient. The CSV is generated by using node-query builder ORM. The resulting CSV is perfectly generated in an environment with my server on Heroku+ClearDB SQL but fails with the error
TypeError: Cannot read property 'length' of undefined
The code portion is as follows:
db.qb.order_by('school_order.school_id', 'desc').distinct()
.select_avg('school_order.student_quality_price', 'average_price')
.select('student_quality.student_quality_name, school_order.unit, school_order.marks_percent,' +
'school_order.fee_amount, school_order.total_marks, school_order.total_value, school_order.po_created_at')
.where({ 'school_order.student_quality_id': matArray, 'school_order.teacher_id': supArray })
.from('school_order')
.join('student_quality', 'school_order.student_quality_id=student_quality.student_quality_id')
.join('supplier', 'supplier.teacher_id=school_order.teacher_id').group_by(' student_quality.student_quality_name').get(function (err, poRes) {
var outputpo = []
console.log("PORESS" + poRes)
if (poRes.length > 0) {
poRes.forEach(po => {
var poDate = new Date(po.po_created_at.toLocaleString()).getTime();
if (poDate >= startDate.getTime() && poDate <= endDate.getTime()) {
outputpo.push(po);
}
});
}
EDIT
Database Connection
var db_settings = {
user: `user`,
password: `password`,
database: `database`,
port:port#,
socketPath: `INSTANCE_STRING`
};
var qb = require('node-querybuilder').QueryBuilder(db_settings, 'mysql', 'single');
module.exports.qb = qb;
qb here is the querybuilder variable. In my logs, console.log("PORESS" + poRes) returns "PORESSUndefined".
Solved
The issue was with the GROUP BY clause which some SQL versions make mandatory to include aggregated columns post the GROUP BY clause. More details here: https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

DataTables warning: JSON data from server could not be parsed. This is a caused by a JSON formatting error in Zend framework while using group

Please help me. I am stuck with one DataTable warning like "DataTables warning: JSON data from server could not be parsed. This is a caused by a JSON formatting error." in zend framework with PHP, JSON encode.
This warning only happens when the table is empty, But This problem is only coming when I use group keyword in sql query, If I do not use group keyword then it gives only one record from the table, but table have more records also.
When I use the following query the output becomes, to show all records only the table have data, if not datatable warning will be shown.
// sql query (models/table/product.php)
public function fetchAllProductItems() {
$oSelect = $this->select()
->setIntegrityCheck(false)
->from(array("p" => "products","b" => "bid"), ('*'))
->joinLeft(array("b" => "bid"), "b.product_id=p.product_id", array('bid_id','bid_amount'))
->joinInner(array("e" => "employees"), "e.employee_id=p.employee_id",array('ename'))
->where("p.verified = ?", "Yes")
->where("p.sold_out = ?", "No")
->group('p.product_id')
->having("p.sale_end_date >= ?", date("Y-m-d"));
return $oSelect;
}
//JSON encode (Modules/sell/controllers/apicontroller)
public function getProductsAction()
{
$oProductModel = new Application_Model_Db_Table_Products();
$oSelect = $oProductModel->fetchAllProductItems();
echo Zend_Json::encode($this->_helper->DataTables($oSelect, array('product_id','e.ename as employee_name','name', 'brand', 'conditions', 'about','image_path', 'reserved_price', 'Max(b.bid_amount) as amount')));
}
The below query will show only one record, if more than one records are having in the table. If the table is empty then I will come "No Data available in table message will come".
// sql query (models/table/product.php)
$oSelect = $this->select()
->setIntegrityCheck(false)
->from(array("p" => "products","b" => "bid"), ('*'))
->joinLeft(array("b" => "bid"), "b.product_id=p.product_id", array('bid_id','bid_amount'))
->joinInner(array("e" => "employees"), "e.employee_id=p.employee_id",array('ename'))
->where("p.verified = ?", "Yes")
->where("p.sold_out = ?", "No")
->where("p.sale_end_date >= ?", date("Y-m-d"));

System.InvalidOperationException: Nullable object must have a value. Linq to sql

I am getting this error in one of my development machine. This error is not happening in other machine which is pointing to same database. Definitely both servers are not identical. I don't know what software which is missing in one server cause this issue. Both machine is running same OS 2008 R2.
using (MYDB.MyDB oDB = new MYDB.MyDB())
{
var query = from t in oDB.Products
where (_ProductId.HasValue?_ProductId==t.Productid:true)
select new Product()
{
ProductId = t.Productid,
ManufacturerId = t.Manufacturerid,
ManufacturingNumber = t.Manufacturingnumber,
CustomProduct = t.Iscustomproduct ? "Yes" : "No",
IsCustomProduct = t.Iscustomproduct,
SubCategoryName = t.Subcategory.Subcategoryname
};
return query.ToList();
}
Any help is highly appreciated
Thanks,
Senthilkumar
I can not reproduce the exception in a comparable case, but the part _ProductId.HasValue?_ProductId==t.Productid:true looks suspect. I would change it as follows and if you're lucky it also solves your problem, otherwise it's an improvement anyway:
var query = from t in oDB.Products;
if (_productId.HasValue)
{
query = query.Where(t => t.Productid == _productId.Value);
}
query = query.Select(t => new Product() {...
Another cause could be that Product.ProductId is not a nullable int.

Linq-Sql IQueryable<T> and chaining OR operations

I'm trying to simulate:
WHERE x.IsActive = true OR x.Id = 5
The following causes 'AND' to be used... how do I simulate an 'OR' condition with IQueryable (qry) and my nullable int, given that other filtering might be involved as with the IsActive filter here?
if (onlyActiveItems) //bool
{
qry = qry.Where(x => x.IsActive == true);
}
if (whenSpecifiedMustIncludeRecordWithThisId.HasValue) //int?
{
qry = qry.Where(x => x.Id == whenSpecifiedMustIncludeRecordWithThisId.Value);
}
I have considered union but its seems the answer to this should be much simpler.
This is one solution which gets around the problem I get with "Nullable object must have a value" when trying the combined all in one answer. What causes the nullable to be evaluated when it is null otherwise?
if (whenSpecifiedMustIncludeRecordWithThisId.HasValue)
{
qry = qry.Where(x => (!onlyActiveItems || (onlyActiveItems && x.IsActive)) || x.Id == whenSpecifiedMustIncludeRecordWithThisId.Value);
}
else
{
qry = qry.Where(x => (!onlyActiveItems || (onlyActiveItems && x.IsActive)));
}
It seems also in some cases the use of the nullable's .Value property makes a difference as seen in another question of mine here Linq to SQL Int16 Gets Converted as Int32 In SQL Command
Try this:
qry = qry.Where(x => (onlyActiveItems
? x.IsActive
: false) ||
(whenSpecifiedMustIncludeRecordWithThisId.HasValue
? x.Id == whenSpecifiedMustIncludeRecordWithThisId
: false) ||
(!onlyActiveItems && !whenSpecifiedMustIncludeRecordWithThisId.HasValue));
Note that we're comparing an int? to an int, not two ints.
I am assuming here that the point of the query is to filter out if certain conditions are met.
If onlyActiveItems is true, it verifies whether the IsActive field is true
If whenSpecifiedMustIncludeRecordWithThisId.HasValue is true it verifies whether the value matches the Id field
If both are true it will logically OR the conditions
If both are false all records are displayed (if this is not the intent, you can remove the last condition)
When working with "int?" I usually compare them using object.Equals(i1, i2), for example
from r in cxt.table
where object.Equals(r.column, nullableInt)
select r
This avoids all nullable issues.