Linq where condition on datetime.ToString() - linq

I have following Linq code
// query = IQueryable<DataClass>
query = query.Where(m => m.Column1.Contains(model.search.value)
|| m.DateTimeColumn2.ToString("dd.MM.yyyy").StartsWith(model.search.value));
return query.ToList() // here the error is thrown
I get NullReferenceException error
Exception has occurred: CLR/System.NullReferenceException An exception
of type 'System.NullReferenceException' occurred in
Microsoft.EntityFrameworkCore.dll but was not handled in user code:
'Object reference not set to an instance of an object.' at
System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at
Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor1.EnumeratorExceptionInterceptor.MoveNext()
if i commented out the line for 2nd column it works
//|| m.DateTimeColumn2.ToString("dd.MM.yyyy").StartsWith(model.search.value)
model.search.value is string value I am trying to filter all columns. The DateTimeColumn2 is in DateTime datatype in the database, but user input string, therefore Iam converting DateTimeColumn2 to string and try to filter to users value. Any idea, what I am doing wrong ?

What happens here is that the part...
|| m.DateTimeColumn2.ToString("dd.MM.yyyy").StartsWith(model.search.value)
...can't be translated into SQL (ToString("dd.MM.yyyy") isn't supported`), so EF-core auto-switches to client-side evaluation.
However, now the whole Where clause is evaluated client-side, including the first part,
m.Column1.Contains(model.search.value)
Now this first part has become susceptible to null reference exceptions. There are entities that have a null for Column1.
When you remove the DateTimeColumn2 predicate the whole statement can be translated into SQL and evaluated by the database.

It is likely that your DateTimeColumn2 can have NULL values which is very normal for DateTime columns. Also you shouldn't convert it to a string but the search value to a datetime. Is the user searching like "01" to mean any 1st date of any month and\year?
query = query.Where(m => m.Column1.Contains(model.search.value)
|| !m.DateTimeColumn2.HasValue
|| m.DateTimeColumn2.ToString("dd.MM.yyyy").StartsWith(model.search.value));
return query.ToList()

If you think that the exception is thrown because of any of the DateTimeColumn2 values might be null, check for non-nullness:
query = query.Where(m => ...
|| (m.DateTimeColumn2 != null &&
m.DateTimeColumn2.ToString("dd.MM.yyyy").StartsWith(model.search.value)));

Related

How to get records where column is not empty or null in laravel?

This is my table:
This is my code I tried:
$socials = SocialIcon::whereNotNull('link')->get()->all();
$socials = SocialIcon::whereNotNull('link')->get();
I want to get all records where column link is not empty.
First you have to understand the difference between NULL and an empty string. NULL is the absence of a value and no memory is allocated for NULL. But empty string is a value with value stored in the memory as "". From your db I can see you have an empty string as a value for the last row in link column. If the value is NULL then you will find NULL is written in the field.
Now as you want to check both NULL and empty you should write it like
$socials = SocialIcon::whereNotNull('link')->orWhere('link','<>','')->get();
this query will both check for NULL and empty value and will return rows with not NULL and empty link value.
Considering a value as NULL same as empty string is not correct. Both are not same.
You can use the below code:
$socials = SocialIcon::where(function($q) {
$q->whereNotNull('link')->orWhere('link','<>','');
})->get();
The resulted query running on DB will be:
select * from social_icons where (link is not null or link <> "")
If you wish to learn more about the Laravel's query builder, click here
You can simply do this
$socials = SocialIcon::where('link', '<>', '')->get();
Read this: https://laravel.com/docs/7.x/queries#where-clauses
Following will also do the job.
$socials = SocialIcon::all();
And then in your template for second case:
#foreach($socials as $social)
#if(!empty($social->link))
your content here
#endif
#endforeach

LINQ Check for Nulls with OR

I have 2 values in table User: Address1, Address2. Both could be null. As part of a filter method, I am attempting something like the below:
var tempUsers = users.Where(q => q.Address1.ToLower().Contains(address.ToLower()) || q.Address2.ToLower().Contains(address.ToLower()));
This is returning a Null Reference Exception, and rightly so.
Linq queries need to be handled against null values
I would be attempting
null.ToLower() and null.Contains() within the query
What is the best way to go around it? If it was a simple 1 field Query, for e.g. just Address1, I would have simply filtered out all items with empty Address1, and continued normally in the second query. In this case, both fields are important to the filtering, as in, the input: address could be either in Address1 or Address2 of the User table.
I know this might not be possible in a 1 liner, but what is the best approach to take in terms of time and performance?
How about this:
var address = (GetAddressFromOuterWorld() ?? String.Empty).ToLower();
var tempUsers = users.Where(user => (user.Address1 ?? String.Empty).ToLower().Contains(address)
|| (user.Address2 ?? String.Empty).ToLower().Contains(address));
This definitely works with LINQ to Object, but probably fails with LINQ to SQL, but in that case you normally write user.Address1 == address || user.Addrss2 == address and your database uses a case-insensitive collate setting.
You can easily add null checks like this.
var tempUsers = users.Where(q =>
(!string.IsNullOrEmpty(q.Address1) && q.Address1.ToLower().Contains(address.ToLower())) ||
(!string.IsNullOrEmpty(q.Address2) && q.Address2.ToLower().Contains(address.ToLower())));

Spring jdbcTemplate executing query

I have a strange problem ,
My Query looks like below.
String tokenQuery = "select id from table
where current_timestamp between
creation_time and (creation_time + interval '10' minute)
and token = '"+Token+"'";
But when I run, jdbcTemplate.queryForLong(tokenQuery) , no matter what , it always throws EmptyDataAccessException.
I am executing this in Oracle
Can we not append dynamic values to string and then pass it as a query and execute ?
What could be the issue ?
I assume that what you get is in fact an EmptyResultDataAccessException. The javadoc of this exception says:
Data access exception thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned.
That simply means that the query is executed fine, and is supposed to return one row, but doesn't return any. So no row satisfies the criteria of your query.
If that is expected, then catch the exception, or use a method that returns a list rather then returning a single value. That way, you can test if the returned list is empty.
That said, you should use a parameterized query instead of concatenating the token like you're doing. This would prevent SQL injection attacks. It would also work even if the token contains a quote, for example.

How to convert iqueryable<string> to string in linq?

i have the following code snippet.
in which i just want to return PartyName as a string.
but i get the error:"Cannot implicity convert type 'System.Linq.Iqueryable to string"
if i want to return only string then what to do?
please help me.
return objDatabase.FAPARs
.Where(f => (f.PARTY_CODE == "P003"))
.Select(f => f.PARTY_NAME);
An IQueryable<string> represents a query which could return any number of strings. You want one string - so you need to decide what to do in various situations:
What do you want to happen if the query has no results?
What do you want to happen if the query has one result? (I assume this is simple :)
What do you want to happen if the query has more than one result?
The set of methods which allow you to determine all of this are:
Single - fail if there isn't exactly one result
SingleOrDefault - fail if there's more than one result, return null if there are no results
First - fail if there are no results, return the first of many
FirstOrDefault - return null if there are no results, or the first of many
Last - fail if there are no results, return the last of many
LastOrDefault - return null if there are no results, or the last of many
In each case, "fail" means "throw an exception". (IIRC it's always InvalidOperationException, at least in LINQ to Objects, but I could be wrong.)
So if you're querying by an ID which must exist (i.e. it's a bug if it doesn't) then Single is probably appropriate. If you're querying by an ID which may not exist, then use SingleOrDefault and check whether the return value is null. If you're not querying by an ID, you probably want to use FirstOrDefault or just iterate over the results.
(Note that the default value being null is due to this being a query returning strings, and string being a reference type. In general it's the default value of the element type - so if you had an IQueryable<int>, the default returned would be 0.)
Try
return objDatabase.FAPARs .Where(f => (f.PARTY_CODE == "P003")) .Select(f => f.PARTY_NAME).SingleOrDefault();
Try this:
return objDatabase.FAPARs.Where(f => (f.PARTY_CODE == "P003")).Single(f => f.PARTY_NAME);
return objDatabase.FAPARs.FirstOrDefault(f => f.PARTY_CODE.Equals("P003")).PARTY_NAME
return objDatabase.FAPARs.OfType<FAPAR>()
.Where(f => (f.PARTY_CODE == PartyCode && f.COMP_NO == ComCode))
.Select(f => f.PARTY_NAME).SingleOrDefault();

SqlDateTime overflow thrown by Typed DataSet Insert

I'm using a Typed DataSet with an Insert statement; I have a table that has a smalldatetime field defined to accept null values. When I insert from a .NET 2.0 FormView, I get a "SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM."
Now, I've read this post, and the parameter as sent to the class constructor is defined as
global::System.Nullable<global::System.DateTime> DoB
So, it looks like it should accept a Nullable obj. Additionally, the generated code is testing the value sent.
if ((DoB.HasValue == true)) {
command.Parameters[6].Value = ((System.DateTime)(DoB.Value));
}
else {
command.Parameters[6].Value = global::System.DBNull.Value;
}
Specifically, the error is occurring when generated SqlClient.SqlCommand.ExecuteScalar() runs:
try {
returnValue = command.ExecuteScalar();
}
So, I guess my question is: how do I use a Typed DataSet to set a blank value (passed from a FormView on CommandName=Insert) to a null in a database?
Ok, so here's what worked for me. First, to reiterate, I've got a Typed DataSet with DataAdapters that's generating the ADO objects. So, on my page, I can create a ObjectDataSource with the type that points to my adapter, and then name the different access methods housed there-in.
No, I have an Insert to a table where basically all the columns are nullable; some varchar, some smalldatetime.
When I submit an empty form, I'd like nulls to be entered. They're not and lots of various errors are thrown. What I ended up doing is subclassing the ObjectDataSource to gain access to the Inserting event. (subclassed for reusability) In the Inserting event, I looped through the InputParameters, and if it was a string and == "", I set it to null. Also, you cannot set ConvertNullToDBNull to true; that causes the strings to fail. This successfully allowed the Nullable to remain null.

Resources