Multiple conditions in linq lambda query - linq-to-sql

Three conditions in linq where clause using lambda expressions
List<Tbl_MVPConsultant> _objConsultants = _datalayer.Get_MVP_Consultants();
_objConsultants = _objConsultants.Where(p => p.Country.ToLower().Contains(SearchTextbox.ToLower()) ||
p.State.ToLower().Contains(SearchTextbox.ToLower()) ||
p.City.ToLower().Contains(SearchTextbox.ToLower())).ToList();
I'm trying to achieve a filter operation three times using the above query .. but i'm getting an error stating object reference not set to an instance of an object ..
Looking for a quick solution.Appreciate early efforts.
Thank you

You won't be able to call p.Country.ToLower if p.Country is null. Put p.Country != null && p.State != null && p.City != null && at the start of the lambda.

Related

How can I use Symfony with a SELECT inside a WHERE clause? I got error

I'm migrating Mysql SQL to Symfony project and I get a error from TLP when I execute the SQL. I guess problem is in the second SELECT inside the WHERE clause.
If I use the original SQL, and I use without symfony framework I have no problems. Furthermore, if I use the clause WHERE with "(vars.ns IN (SELECT...))" I get no errors, but SQL must not be like that.
date_default_timezone_set('UTC');
$em = $this->getContainer()->get('doctrine')->getManager();
$query = $em->createQuery("SELECT vars.dm, vars.ns, vars.mc, vars.ac, vars.sf, vars.cn, vars.mp, vars.ta, vars.mo, vars.mh, vars.pa, vars.sp, vars.so, vars.sh, vars.sn, vars.mm, vars.ms, vars.gs, vars.a1, vars.a2, vars.updated FROM BaseBundle:Vars vars WHERE (SELECT device.id FROM BaseBundle:Device device WHERE device.ns = vars.ns AND device.idUser IS NOT NULL AND device.idUser != '422' AND device.idUser != '819') AND vars.idDevice IS NOT NULL AND vars.updated > :time")->setParameter('time', date('Y-m-d H:i:s', strtotime('-31 days')));
$historics = $query->getResult();
And I get this error:
[Doctrine\ORM\Query\QueryException]
[Syntax Error] line 0, col 233: Error: Expected Literal, got 'SELECT'
This SQL must return 276 rows and it does, but not in symfony. Any idea about the issue?
Thank you so much,
UPDATE:
MYSQL ORIGINAL QUERY
SELECT
vars.dm,
vars.ns,
vars.mc,
vars.ac,
vars.sf,
vars.cn,
vars.mp,
vars.ta,
vars.mo,
vars.mh,
vars.pa,
vars.sp,
vars.so,
vars.sh,
vars.sn,
vars.mm,
vars.ms,
vars.gs,
vars.a1,
vars.a2,
vars.updated
FROM
table_3.vars
WHERE
(SELECT
device.id_user
FROM
table_3.device
WHERE
device.ns = vars.ns
AND device.id_user IS NOT NULL
AND device.id_user != '422'
AND device.id_user != '819')
AND vars.id_device IS NOT NULL
AND vars.updated > NOW() - INTERVAL 30 DAY
First of all Doctrine does not use SQL it uses DQL. DQL looks similar, but works a bit differently when you talk about properties and fields. While creating Doctrine Query you have to use property names rather than field names and entity which you are referring to must exist with such properties. Is your BaseBundle:Vars entity present? and does it have properties mentioned in query string? And how about device entity?
You get this error
Expected Literal, got 'SELECT'
because doctrine tries to parse the subquery condition:
(SELECT device.id FROM BaseBundle:Device device WHERE device.ns = vars.ns AND device.idUser IS NOT NULL AND device.idUser != '422' AND device.idUser != '819')
and expects it to be a Literal
That happens because no comparison has been defined for the above condition and doctrine assumes that this should be a literal and when "sees" that it starts with "SELECT", it throws the error.
To overcome this, add a comparison (eg > 0) to the condition:
(SELECT device.id FROM BaseBundle:Device device WHERE device.ns = vars.ns AND device.idUser IS NOT NULL AND device.idUser != '422' AND device.idUser != '819') > 0

How do I use 'OR' operator to return all rows if string is empty in linq to sql

I've a linq query :
var Employees = db.EmployeeMasterAs
.Where(x => x.SystemCode == SysCode && x.EmployeeCode == EmpCode)
.ToList();
the above query works fine if all values in the where clause are provided. If EmpCode is supplied a value, it returns the corresponding data, which works fine. However, I've no idea about how to return all rows if EmpCode is not supplied.
If I were to use SQL, I would have done it this way :
SELECT * FROM EmployeeMasterAs
WHERE SystemCode == #SysCode AND (EmployeeCode == #EmpCode or '')
I've no idea how to translate the above query into linq syntax. Any Help will be deeply appreciated, Thanks in Advance :)
you can even write something like this
...&& (EmpCode == null || x.EmployeeCode == EmpCode) )
which i find simplier than #Dr Ivol

NHibernate.ISession.Linq<T>.Where(expression) retrieves whole table

I am using NHIbernate against MySql, and when I use the following statement, NHibernate Profiler shows me that the query passed to MySql is basically SELECT * FROM tablename with NO WHERE clause. The LINQ expression isn't applied until after all the data are retrieved. This is obviously not acceptable from a performance standpoint. What am I doing wrong?
Session.Linq<T>().Where(expression).AsQueryable()
Thanks!
[UPDATE]
As #GertArnold guessed, the call preceding this was:
public IQueryable<Student> FindByExpression(Func<Student, bool> expression)
The expression was:
_studentRepository.FindByExpression(t =>
(t.Teacher.Id == dto.TeacherId) &&
(t.Id != dto.Id) &&
(
(t.ExternalId != null && student.ExternalId != null
)
You should use an Expression<Func<T, bool>> instead of Func<T, bool>.

Using one LINQ statement with different parameters

I have a pretty complex linq statement I need to access for different methods. Each of these methods may need to see the resulting data with different parameters. For one method it may be a project code, for another it may be language. The statement is pretty much the same it's just the where part which changes.
I have not been able to figure out how to use different where statements without duplicating the entire linq statement, and that just isn't dry enough for me.
For example (greatly simplified):
var r = from c in customer
where c.name == "some name"
// or it may be
var r = from c in customer
where c.customerId == 8
Is there a way to have both of these in the same statement so I can use one or the other based on what I am doing? I tried an if statement to use one of the where statements or the other, and that didn't go over very well.
You can do it like this:
var r = from c in customer
select c;
if (CustomerName != null)
r = r.Where(c => c.name == CustomerName);
if (CustomerID != null)
r = r.Where(c => c.customerId == CustomerID);
You could make these else if if only one should apply, in my example any criteria that wasn't null would be applied to the query to filter on.
what about something like this?
var useIdForFiltering = false;
var r = from c in customer
where (useIdForFiltering && c.customerId == 8) || (c.name == "some name")
You can pass in a Func delegate to your function (the Where clause takes a Func delegate with a boolean return type). Then use this delegate in the Where clause.

Entity Framework - MySQL - Null Comparison!

Whats wrong with following code? :(
int? parentFolderId = null;
if( this.Request.QueryString ["folderId"] != null )
parentFolderId = Convert.ToInt32( this.Request.QueryString ["folderId"] );
f = ( from x in this.EntityDataContext.folders
where x.parent_id == parentFolderId
select x ).ToList();
It returns nothing! Though there ARE records in database with parent_id as NULL.
However, when I explicitly state NULL; it works!
f = ( from x in this.EntityDataContext.folders
where x.parent_id == null
select x ).ToList();
What could be the issue?
PS: I hate working with mysql using Entity Framework .... every damn simple thing has million issues!
Long Shot
f = ( from x in this.EntityDataContext.folders
where ((parentFolderId!=null && x.parent_id == parentFolderId)
||(parentFolderId==null && x.parent_id == null))
select x ).ToList();
Yeah, this seams wired, and I guess your first example should work just fine with MsSql.
Maybe it's time to file a bug to authors of Linq to MySql ?
I had this kind of problem in sql server and in sql server the generated query looks like "parent_id = null" when you are working on a nullable field. And that query returns nothing even parent_id is null.
The tricky way in here is, you should force EF to create a query like "parent_id is null" and the code I tried in linq was;
if(parentFolderId.HasValue)
{
f = ( from x in this.EntityDataContext.folders
where x.parent_id == parentFolderId
select x ).ToList();
}
else
{
f = ( from x in this.EntityDataContext.folders
where !x.parent_id.HasValue
select x ).ToList();
}
I know this does not seem a perfect way to do this but, this is how I could get rid of that issue.
You'll probably find there's an issue involving using DBNull or something similar. I would think that in the second case (where you explicitly state "null") that Linq is automatically transforming it to DBNull in the background.
perhaps try something along the lines of:
where x.parent_id == ( parentFolderId == null ? DBNull.Value : parentFolderId )
Hope that puts you on the right track!
This is connector bug and I have reported at mysql.