开发者

Strange .Where() behaviour. Somebody has an explanation?

Original

I don't get why the Where() clause doesn't give me the right results in the last example.

It isn't any different is it? Why does C# behaves differently?

transactions = IEnumerable<Transaction> //pseudocode 

//This works: It gives me the transaction I need.
DateTime startDate = DateTime.Parse(parameter.Constraint); 
transactions = transactions.Where(T => T.date >= startDate);  

//This doesn't work... No actual code changed, only the way of writing it...
//I get 0 results.
 transactions = transactions.Where(T => T.date >= D开发者_如何学CateTime.Parse(parameter.Constraint));

Edit

Ok, it is indeed relevant to mention that transactions is loaded using Entity Framework.

transactions = this.db.Include("blablabla").OrderByDescending(T => T.date);

Maybe that's why it's doing weird? Because of the way Entity Linq works?


The only way this could actually be happening is if you were modifying parameter or parameter.Constraint somehow while you're enumerating through transactions. So if you're not doing that, look at whether you're actually observing what you think you're observing.

In principle, this should work fine.

EDIT: One obvious way you could be confused about your observation is if you didn't check the results of (actually evaluate) the lazy Where enumeration until later on, when parameter had changed. If you put a ToArray on the end to evaluate it immediately, you might find that it "magically" fixes itself.


Undoubtedly a variation of

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!689.entry

http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx


I just tried this and it works fine:

class Program
{
    public class Transaction { public DateTime date { get; set; } }
    public class Parameter { public string Constraint { get; set; } }
    public static void Main()
    {
        IEnumerable<Transaction> transactions = new List<Transaction> {
            new Transaction { date = new DateTime(2009, 10, 5) },
            new Transaction { date = new DateTime(2009, 11, 3) }
        };
        Parameter parameter = new Parameter { Constraint = "2009-11-01" };
        DateTime startDate = DateTime.Parse(parameter.Constraint);

        // Version 1.
        transactions = transactions.Where(T => T.date >= startDate);

        // Version 2.
        transactions = transactions.Where(T => T.date >= DateTime.Parse(parameter.Constraint));

    }
}

You must be omitting an important detail. Perhaps you could try reducing your code to the simplest possible example that still reproduces the bug. In doing so, you will probably discover the solution. If you still can't see the problem you can post the short, compiling, non-working version here and I'm sure someone will spot the problem quickly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜