UPDATE:
Hmmm, looks like this is more complex than I originally thought. Turns out String.Equals with a StringComparison overload is not supported by Linq-to-SQL. But, the fact that you get the error means that Linq-to-SQL is trying to take the entire expression and turn it into SQL. Which in turn means that all comparisons will happen according to the native collation of the database-- which by default is case-insensitive. So even though Linq-to-SQL won't support case-insensitive comparisons, you probably don't need case-insensitive comparisons since you can rely on SQL Server doing them by default.
So, provided you haven't changed the collation of your string columns in your table from case-insensitive (the default) to case-sensitive, the following code should work:
var addresses = from a in Addresses
where String.Equals (u.Street_address, a.Street1)
&& String.Equals (u.City, a.City)
&& String.Equals (u.State, a.State)
&& String.Equals (u.ZipCode, a.Zip)
select a;
It's possible this may work too:
var addresses = from a in Addresses
where u.Street_address == a.Street1
&& u.City == a.City
&& u.State == a.State
&& u.ZipCode == a.Zip
select a;
But, based on my reading of this MSDN article (excerpted below), I suspect that only using ==
(instead of String.Equals() may not work) :
Null semantics
LINQ to SQL does not
impose null comparison semantics on
SQL. Comparison operators are
syntactically translated to their SQL
equivalents. For this reason, the
semantics reflect SQL semantics that
are defined by server or connection
settings. For example, two null values
are considered unequal under default
SQL Server settings, but you can
change the settings to change the
semantics. LINQ to SQL does not
consider server settings when it
translates queries.
A comparison with the literal null is
translated to the appropriate SQL
version (is null or is not null).
In other words, if I'm reading this MSDN text correctly, it sounds like Linq-to-SQL translates ==
into =
in T-SQL, while (as your experiment showed) String.Equals is translated correctly as a check for IS NULL
followed by a check using =
. If you have a chance to test just ==
, I'd be interested to see whether Linq-to-SQL emits the IS NULL
checks or not.
Given the complexity here (Linq-to-SQL translating C# into SQL, and results back to C#) your best bet in cases like this is to try multiple variations (e.g. == vs. Equals()) and pick the one that works, since there are enough moving parts that it's hard to anticipate ahead of time which variation will work best.
OLD ANSWER (ignore this):
Consider using the static String.Equals
method instead of ==
and ToLower()
. You'll avoid the null-reference problems (and simplify your code) because nulls are OK to pass into that method and it supports a case-insensitive check.
var addresses = from a in Addresses
where String.Equals (u.Street_address, a.Street1, StringComparison.OrdinalIgnoreCase)
&& String.Equals (u.City, a.City, StringComparison.OrdinalIgnoreCase)
&& String.Equals (u.State, a.State, StringComparison.OrdinalIgnoreCase)
&& String.Equals (u.ZipCode, a.Zip, StringComparison.OrdinalIgnoreCase)
select a;
Although if your database is already case-insensitive, depending on how Linq-to-SQL splits the work between SQL and C# code, you may not need the insensitivity check at all-- although if it were me, I'd rather be safe and enure you always enforce the case check.