Date fiIter Issues in LINQ - linq

I have an ASPX page that collects 5 optional search criteria from a user and returns the result in a grid. Once the criteria are collected and the view button clicked, the code behind generates the filter like we have below
// aSearchCriteria is a class that holds the criteria
...
string filter = string.Empty;
if (!string.IsNullOrEmpty(aSearchCriteria.RegistrationNumber)) filter =
"f.BusinessRegistrationNumber = '" +
aSearchCriteria.BusinessRegistrationNumber + "'";
if (aSearchCriteria.ChangedStartDate != null && aSearchCriteria.ChangedEndDate != null)
{
if (!string.IsNullOrEmpty(filter))
{
filter += " && f.ChangedDate >= '" +
aSearchCriteria.ChangedStartDate.ToShortDateString() +
"' && f.ChangedDate <= '" +
aSearchCriteria.ChangedEndDate.ToShortDateString() + "'";
}
else
{
...
}
}
...
Using (CustomerEntities db = new CustomerEntities())
{
if (!string.IsNullOrEmpty(filter))
{
filter = "f => " + filter;
**return db.Customers.Where(filter).ToList();**
}
else
...
}
...
Sample:
"filter" value: f => f.ChangedDate > '01/01/2012' && f.ChangedDate < '14/01/2012'
Anytime I execute this I get this error message:
The query syntax is not valid. Near term '>', line 6, column 5.

you don't want to make the filter a string. What you should do instead is apply the filtering to the IQueryable you get. Something like:
var customers = db.Customers.AsQueryable();
if (aSearchCriteria.ChangedStartDate != null && aSearchCriteria.ChangedEndDate != null)
{
customers = customers
.Where(c => c.ChangedDate >= aSearchCriteria.ChangedStartDate &&
c.ChangedDate >= aSearchCriteria.ChangedEndDate);
}
// ... apply other filters as necessary
return customers.ToList();

Assuming you are using ObjectQuery.Where(string)
the string predicate should look like
"it.ChangedDate > '01/01/2012' && it.ChangedDate < '14/01/2012'"
(no f=> and the alias of the table is it)
Please confirm it helped :)

Related

Date "less but not empty" custom search in free-jqgrid

I am using free-jqgrid 4.15.4 for showing the data. There i have a need to search date column with Date less but not empty filter, but it is not filtering correctly. In result it gives me date which are greater than searched date.
Below code is used for custom filter in date column:
customSortOperations: {
dlne: {
operand: "<!=''",
text: "Date less but not empty",
filter:function (options) {
var p = this.p, iCol = p.iColByName[options.cmName], cm = p.colModel[iCol],
newformat = cm.formatoptions != null && cm.formatoptions.newformat ?
cm.formatoptions.newformat :
$(this).jqGrid("getGridRes", "formatter.date.newformat"),
srcformat = cm.formatoptions != null && cm.formatoptions.srcformat ?
cm.formatoptions.srcformat :
$(this).jqGrid("getGridRes", "formatter.date.srcformat"),
fieldData = $.jgrid.parseDate.call(this, srcformat, options.item[options.cmName]),
searchValue = $.jgrid.parseDate.call(this, newformat, options.searchValue);
var retFData = convertD(fieldData), t = new Date(retFData);
if ((retFData.getFullYear() < searchValue.getFullYear()) && (retFData.getMonth() < searchValue.getMonth()) && (retFData.getDate() < searchValue.getDate())) {
return true
}
}
},
}
The convert function that I am using for converting string into date format, is written below:
function convertD(dateField) {
var date = new Date(dateField),
mnth = ("0" + (date.getMonth() + 1)).slice(-2),
day = ("0" + date.getDate()).slice(-2);
// year= (date.getFullYear())
var retVal = [day, mnth, date.getFullYear()].join("/");
return retVal;
}
I have taken the idea from here and made some changes but seems no avail. So requesting community to help on this.
The code of dlne could be fixed to for example the following:
dlne: {
operand: "<!=''",
text: "Date less but not empty",
filter: function (options) {
var p = this.p, iCol = p.iColByName[options.cmName], cm = p.colModel[iCol],
newformat = cm.formatoptions != null && cm.formatoptions.newformat ?
cm.formatoptions.newformat :
$(this).jqGrid("getGridRes", "formatter.date.newformat"),
srcformat = cm.formatoptions != null && cm.formatoptions.srcformat ?
cm.formatoptions.srcformat :
$(this).jqGrid("getGridRes", "formatter.date.srcformat"),
fieldData, searchValue;
// the exact condition to test for "empty" depend on the format of your data
if (!options.item[options.cmName]) {
return false; // ignore empty data
}
fieldData = $.jgrid.parseDate.call(this, srcformat, options.item[options.cmName]);
searchValue = $.jgrid.parseDate.call(this, newformat, options.searchValue);
return fieldData.getFullYear() < searchValue.getFullYear() ||
(fieldData.getFullYear() === searchValue.getFullYear() &&
fieldData.getMonth() < searchValue.getMonth()) ||
(fieldData.getFullYear() === searchValue.getFullYear() &&
fieldData.getMonth() === searchValue.getMonth() &&
fieldData.getDate() < searchValue.getDate());
}
}
see https://jsfiddle.net/OlegKi/51vfn4k9/11/

Alternative to using dryRun to differentiate a Standard and Legacy SQL query in BigQuery?

The What
Does anyone know a better way of identifying/differentiating between a view or query written in Legacy or Standard SQL, using the BigQuery API?
The only method that came to mind was to run the SQL with the dryRun property set to true (this would incur the minimum processing overhead) and if it fails with a message that included the phrase "Try using standard SQL" I could assume it was legacy SQL, otherwise it works and is Standard. E.g.
{
...
"code": 400,
"message":
"Invalid table name: `my-project.my_dataset.hello_world`
[Try using standard SQL (https://cloud.google.com/bigquery/docs/reference/standard-sql/enabling-standard-sql)]."
}
The Why
I'm maintaining an integration layer (written in Cloud Functions - Node.js 8) that migrates data using the BigQuery API.
Unfortunately the user community has been permitted to write views and queries in either Standard or Legacy SQL. Due to the numerous limitations when dealing with Legacy SQL I'd like to detect which queries and views are written using it, allowing me to adjust the processing method accordingly.
Does anyone know a better way of identifying/differentiating between a view or query written in Legacy or Standard SQL, using the BigQuery API?
You can try and use javascript regex to identify the type of the SQL.
You can use the below code snippet as a baseline
isStandardSql(idString) {
let isStandard, fullId, partialId, projectId = '';
// This 'if' checks if the provided idString is of type standard and makes sure there is only one ':' in the expression (as in legacy syntax)
const splitted = idString.split(/[:.]/g);
if (splitted.length > 3) {
const __ret = this.try2findProjectId(idString, projectId);
idString = __ret.idString;
projectId = __ret.projectId;
}
if ((idString.match(/:/g))) {
// Regex that checks if the format of the id match legacy
let matched = idString.match(/([\[]([^[]|[\[][\]])*[\]])/g);
if (matched && matched[0]) {
fullId = projectId + matched[0].substring(1, idString.length - 1);
isStandard = false;
} else {
this.errorMessage("First Regex", idString);
}
// Same as the first only that here instead of ':' we are looking for '.' and we want to make sure there is more than 1 (as in standard syntax)
} else if ((idString.match(/\./g) && idString.match(/\./g).length === 2)) {
// Regex that checks if the format of the id match standard
let matched = idString.match(/(`([^`]|``)*`)/g);// ? idString.match(/(`([^`]|``)*`)/g) : [idString];
if (matched && matched[0]) {
fullId = projectId + matched[0].substring(1, idString.length - 1);
isStandard = true
} else if(!matched && idString){
fullId = projectId + idString;
isStandard = true;
}
else {
this.errorMessage("Second Regex", idString);
}
}
else {//projectID.dataset
// In case of id without projectId of proxy "use" project.dataset
if(splitted.length === 2) {
fullId = '';
if (idString[0] === '[' && idString[idString.length - 1] === ']') {
isStandard = false;
}
else if (idString[0] === '`' && idString[idString.length - 1] === '`') {
isStandard = true;
}
partialId = idString.replace(/`|\[|\]/g, '')
}
else {
this.errorMessage("Third Regex", idString);
}
}
// Return values is flag the determine the type (standard or legacy) and id without staring/ ending chars (``, [])
return {
isStandard,
fullId: fullId,
partialId: partialId
};
}
try2findProjectId(idString, projectId)
{
let numOfInstances = 0
for (let i = idString.length; i > 0; i--) {
const char = idString[i - 1]
if (char === ':' || char === '.') {
numOfInstances++
if (numOfInstances === 2) {
projectId = idString.substring(1, i - 1)
idString = idString.substring(i - 1, idString.length)
idString = idString[idString.length - 1] === '`' ? '`' + idString : idString
idString = idString[idString.length - 1] === ']' ? '[' + idString : idString
}
}
}
return {idString, projectId}
}

Result set doesn't have value

I am making board and now trying to make search function.
but values doesn't come out if I search keyword
I have tried to run on oracle with printed sql and parameter(optionText,searchText..) it worked fine but result set doesnt have value
public List<boardVO> getBoardList(String optionText,String searchText,int totalNum , int nowPage){
List<boardVO> list = new ArrayList<boardVO>();
try {
connectDB();
String sql = "select * from "
+ "(select rownum as rnum,recordno,userid,title,content,views,regdate from";
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
sql += " (select * from boardlist where ? like ?))";
}else{
sql += " boardlist)";
}
sql += "where rnum>=? and rnum<=? order by recordno desc";
pstmt = conn.prepareStatement(sql);
int finalNum = totalNum -(5*(nowPage-1));
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
pstmt.setString(1, optionText);
pstmt.setString(2, "%"+searchText+"%");
if(finalNum>4) {
pstmt.setInt(3, finalNum-4);
pstmt.setInt(4, finalNum);
}else {
pstmt.setInt(3, 1);
pstmt.setInt(4, finalNum);
}
}else {
pstmt.setInt(1, finalNum-4);
pstmt.setInt(2, finalNum);
}
rs = pstmt.executeQuery();
while(rs.next()) {
boardVO vo = new boardVO();
System.out.println("while");
vo.setRecordNo(rs.getInt(2));
vo.setUserid(rs.getString(3));
vo.setTitle(rs.getString(4));
vo.setContent(rs.getString(5));
/* System.out.println(vo.getContent()); */
vo.setViews(rs.getInt(6));
vo.setRegdate(rs.getString(7));
list.add(vo);
}
} catch (Exception e) {
System.out.println("get board list error");
e.printStackTrace();
}finally {
closeDB();
}
return list;
}
I think this is your problem:
(select * from boardlist where ? like ?)
It looks like you are trying to pass both a column name and a searchable value to your query: you can't do this with parameters. Both assignments will be treated as literals, so your executed code will be something like this:
select * from boardlist where 'COLUMN_NAME` like '%some string%'
Perfectly valid SQL, just won't return any results.
If this is the case you need to change the assemblage of the statement to include the column name ...
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
sql += " (select * from boardlist where " + optionText + " like ?))";
}else{
... and remove the parameter assignment:
if(optionText!=null && !optionText.equals("") && searchText!=null &&!searchText.equals("")) {
pstmt.setString(1, "%"+searchText+"%");

Get only one value from the table using LINQ

I have a Customer Table and a Address Table (customer_id, address_forename, address_surname, address_street, address_city, address_zip,
address_storedtime) where customer_id as a foreign key.
One customer can have several address.
Now I am trying to get only the last entered address using LINQ as bellow which should allow me put the address in a string and return that:
CODE:
var customerAddress = (from c in myDB.address
where (c.customer_id == customerId)
select new
{
c.customer_id,
c.address_forename,
c.address_surname,
c.address_street,
c.address_city,
c.address_zip,
c.address_storedtime
}).GroupBy(g => new
{
Customer = .customer_id,
Address = g.address_forename + " " + g.address_surname + " " + g.address_street + " " + g.address_city + " " + g.address_zip
}).Select(g => new
{
g.Key.Customer,
g.Key.Address,
StoredTime = g.Max(x => x.address_storedtime)
}).Disinct();/*First();*/
string result = "";
foreach (var ad in customerAddress)
{
if (ad.Address != null)
{
result = ad.Address;
}
break;
}
return result;
I am getting same address string for different addresses in DB for the Customer whereas I am trying to get only one.
Since you're already filtering by customer id, the grouping clause isn't necessary. You should be able to just order the results for the customer descending and project the address much more simply.
var customerAddress = (from c in myDB.address
where (c.customer_id == customerId)
orderby c.address_storedtime descending
select c.address_forename + " " + c.address_surname + " " + c.address_street + " " + c.address_city + " " + c.address_zip)
.FirstOrDefault();
Replace your foreach by
var result =
customerAdress.Any(ad => ad.Address != null)
? customerAdress.Last(ad => ad.Address != null).Address
: default(string);

Converting from dataset to list in linq

I have dataset function which is as below,
public DataSet GetUpodBrandList(string criteria, string locationId)
{
using (SqlConnection conn = new SqlConnection(this.ConnectionString))
{
string query;
if (criteria == "")
query = "select distinct brandDesc " +
"from arabia_upod_item_master " +
"where locationId = '" + locationId +
"' order by brandDesc";
else
query = "select distinct brandDesc " +
"from arabia_upod_item_master " +
"where brandDesc like '%" + criteria + "%' " +
"and locationId = '" + locationId + "'
order by brandDesc";
conn.Open();
SqlCommand command = new SqlCommand(query, conn);
return this.ExecuteDatasetStoredProc(command);
}
}
I am trying to convert it into linq as follow,
public static List<DataContext.arabia_upod_item_master> GetUpodBrandList(
string criteria,
string locationId)
{
List<DataContext.arabia_upod_item_master> m =
new List<DataContext.arabia_upod_item_master>();
using (var db = UpodDatabaseHelper.GetUpodDataContext())
{
db.ObjectTrackingEnabled = false;
if (criteria == "")
m = db.arabia_upod_item_masters.Where(
i => i.locationId == Convert.ToInt32(locationId))
.OrderBy(i => i.brandDesc)
.Distinct()
.ToList();
else
m = db.arabia_upod_item_masters.Where(
i => i.brandDesc.Contains(criteria) &&
i.locationId == Convert.ToInt32(locationId))
.OrderBy(i => i.brandDesc)
.Distinct()
.ToList();
return m;
}
}
But I don't know how to select distinct brandDesc in the above function (as in the previous function). I am simply using Distinct(). Is it right? or is there any other way to achieve it? Also, if there was 'case' in query in my old function (i.e the first one above) then how will i convert it to linq in the second function. Any other things to worry about while converting to linq?
Put a .Select(i => i.brandDesc) just before each Distinct call. You'll also need to change your List<x> so x is whatever the type of brandDesc is.
If I were to refactor you whole method, I'd do something like the following. I've pulled out code that is common to both forms of the query, and tweaked in a couple of other places.
public static IList<string/* I assume*/>GetUpodBrandList(
string criteria, string locationId)
{
// only do this once, not once per item.
int locatId = Convert.ToInt32(locationId);
using (var db = UpodDatabaseHelper.GetUpodDataContext())
{
db.ObjectTrackingEnabled = false;
// This is a common start to both versions of the query.
var query = db.arabia_upod_item_masters
.Where(i => i.locationId == locatId);
// This only applies to one version of the query.
if (criteria != "")
{
query = query.Where(i => i.brandDesc.Contains(criteria));
}
// This is a common end to both version of the query.
return query
.Select(i => i.brandDesc)
.Distinct()
// Do the ordering after the distinct as it will
// presumably take less effort?
.OrderBy(i => i.brandDesc)
.ToList();
}
}

Resources