views:

428

answers:

4

I'm trying to do a query like so...

query.Where(x => !string.IsNullOrEmpty(x.PropertyName));

but it fails...

so for now I have implemented the following, which works...

query.Where(x => (x.PropertyName ?? string.Empty) != string.Empty);

is there a better (more native?) way that LINQ handles this?

EDIT

apologize! didn't include the provider... This is using LINQ to SQL

+1  A: 

Can you explain why it fails? What values are getting through that you do not expect to make it. I can't see anything wrong with this particular code (or what would differentiate it from the second example).

JaredPar
+1  A: 

This will work fine with Linq to Objects. However, some LINQ providers have difficulty running CLR methods as part of the query. This is expecially true of some database providers.

The problem is that the DB providers try to move and compile the LINQ query as a database query, to prevent pulling all of the objects across the wire. This is a good thing, but does occasionally restrict the flexibility in your predicates.

Unfortunately, without checking the provider documentation, it's difficult to always know exactly what will or will not be supported directly in the provider. It looks like your provider allows comparisons, but not the string check. I'd guess that, in your case, this is probably about as good of an approach as you can get. (It's really not that different from the IsNullOrEmpty check, other than creating the "string.Empty" instance for comparison, but that's minor.)

Reed Copsey
A: 

This won't fail on Linq2Objects, but it will fail for Linq2SQL, so I am assuming that you are talking about the SQL provider or something similar.

The reason has to do with the way that the SQL provider handles your lambda expression. It doesn't take it as a function Func<P,T>, but an expression Expression<Func<P,T>>. It takes that expression tree and translates it so an actual SQL statement, which it sends off to the server.

The translator knows how to handle basic operators, but it doesn't know how to handle methods on objects. It doesn't know that IsNullOrEmpty(x) translates to return x == null || x == string.empty. That has to be done explicitly for the translation to SQL to take place.

Brian Genisio
+2  A: 

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=367077

Problem Statement
It's possible to write LINQ to SQL that gets all rows that have either null or an empty string in a given field, but it's not possible to use string.IsNullOrEmpty to do it, even though many other string methods map to LINQ to SQL. Proposed Solution Allow string.IsNullOrEmpty in a LINQ to SQL where clause so that these two queries have the same result:

var fieldNullOrEmpty =
from item in db.SomeTable
where item.SomeField == null || item.SomeField.Equals(string.Empty)
select item;

var fieldNullOrEmpty2 =
from item in db.SomeTable
where string.IsNullOrEmpty(item.SomeField)
select item;

Other Reading:
1. DevArt
2. Dervalp.com
3. StackOverflow Post

RSolberg