简体   繁体   中英

Entity framework + Lambda expression null comparison not working

i have a simple select:

this works:

User = ent.e_user.FirstOrDefault(x => x.usr_name == UserName && x.password == null);

Even if var Password is equal to null

this doesn't work:

String Password = null;

if(Password == null)
{
 //it enters here
}

    User = ent.e_user.FirstOrDefault(x => x.usr_name == UserName && x.password == Password);

Using the variable, it's not returning.

any idea?

Are you running against a SQL Server database? Do you have access to the SQL Server Profiler?

I think a look at the SQL being executed would tell you a lot. For example, if Password is passed as a parameter (as I believe it would be) is it compared to the column password with a simple "="? That will always return false, because

SET @1 = Null;
SELECT *
FROM   table
WHERE  password = @1;

... will never return any records, even if every record has a null password field.

You could try something like this:

User = ent.e_user.FirstOrDefault(
    x => x.usr_name == UserName && 
        (x.password == Password || (x.password == null && Password == null)
);

A detailed explanation can be found in this article: NULL Value Handling in Entity Framework . Beware that EF 5.0, 6.0 and 6.1 handle the nullable values differently. In EF 5.0, you will need to manually test for nulls like the answer above; an equation comparison between two variables does not test for nulls by default. You can also turn on the UseCSharpNullComparisonBehavior property manually in the DbContext.ContextOptions to achieve the same effect. In EF 6.0, null comparison is turned on by default, but probably over-aggressively and even on non-nullable columns, resulting in slower performance. EF 6.1 is supposed to have tweaked the algorithm to only test nulls when truly needed.

The && operator is an 'early terminating' operator. That means that if the result of the first condition is false (ie, usr_name is not the same value as UserName ), then it will never check the password - there's no point. If the first part of the 'and' is false then the result of evaluating all operators is false. If you are determined to check the password, either swap the order of the usr_name and password check, change the && to & or name sure that x.usr_name evaluates to 'true'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM