I was wondering about the performance difference between these two scenarios and what could the disadvantages be over each other?
First scenario :
public class Helper //returns IQueryable
{
public IQueryable<Customer> CurrentCustomer
{
get{return new DataContext().Where(t=>t.CustomerId == 1);
}
}
public class SomeClass
{
public void Main()
{
Console.WriteLine(new Helper().CurrentCustomer.First().Name;
}
}
The second scenario :
public class Helper //returns Enumerated result
{
public Customer CurrentCustomer
{
get{return new DataContext().First(t=>t.CustomerId == 1);
}
}
public class SomeClass
{
public void Main()
{
Console.WriteLine(new Helper().CurrentCustomer.Name;
}
}
Thanks in advance.
Well, the main difference that I can see is when the query is executed and what else you can do with the query.
For example, suppose your
Customerobject has some large fields. Using the second approach, you will always fetch them. Using the first approach you could write:That would then only need to query the single field in the database. In terms of timing, the query will only be executed when you actually request the data (which is how it’s able to wait until after you’ve used
Selectto work out what to put in the query in the above case). That has pros and cons – it can make it harder to reason about, but it can save some work too. In terms of the “reasoning about” side, you know that once you’ve got a customer, you’ve got an object you can just work with. If you use the same queryable twice though, you need to know whether your LINQ query provider is going to cache the result… if you write:will that issue the query once or twice? I suspect it very much depends on the provider, but I wouldn’t like to make any guesses about specific ones.
The other thing to think about is how easy it is to use the API you’re building. Personally I’d normally find it easier to use an API which gives me the data I want rather than a query I can fetch that data from. On the other hand, it is slightly less flexible.
One option would be to allow both – have a GetCurrentCustomerQuery() and a GetCurrentCustomer() method. (I probably wouldn’t make them properties myself, but that’s merely a matter of personal preference.) That way you can get the flexibility you want when you really need it, but have a simple way of just getting the current customer as an object.