The 'var' keyword is used here because you can't always know the type returned by the query. Or it's not important for example.
Say we have this query:
var q = from c in metaData.Customers where c.Country=="USA" select c;
very simple. Now, when I do:
foreach(var v in q)
{
// do something
}
I enumerate over it. This internally calls GetEnumerator() and that calls the execute method on the object referred to by q. Which simply does an entity collection fetch and as the enumerator is required, the enumerator of the entity collection is returned.
However, if I do:
List<CustomerEntity> customers = q.ToList();
the query is also executed, but it's less efficient: the query is executed internally, and enumerated and copied into a new List<CustomerEntity>.
So if you just want to have the EntityCollection<CustomerEntity> (or for selfservicing, CustomerCollection), you are out of luck. So we introduced the interface. You can cast the query to ILLBLGenProQuery and then you can call Execute. This simply executes the query and returns the result. This has the advantage that you get the result in an entitycollection with which you can create views in memory and have other fancy features
Linq's design is a bit crippled. So you have two types of queries: queries which execute directly, which are queries which return a scalar value, e.g. the count, and you have queries which are only executed when you enumerate them. That second group is in our case always returned as an LLBLGenProQuery<T>. This is not really useful unless you know what 'T' is. For entities this is doable, in the query above, T is CustomerEntity. However in the case of anonymous types, this isn't possible, as these types are created by the compiler.
So to access the features of LLBLGenProQuery<T>, you need an interface without the generic argument. Hence 'ILLBLGenProQuery'
Your second query is less efficient, as you copy the data over to a new collection. What you can do is this:
CompanyCollection ret;
var q = from c in _metaData.Company
join o in _metaData.CompanyStateServiced on c.CompanyId equals o.CompanyId
where o.AddressStateId == stateId
orderby c.CreatedDateTimeUtc descending
select c;
int count = q.Count();
//Do something with count
ret = ((ILLBLGenProQuery)q).Execute<CompanyCollection>();
LogCompanyView(ret);
return ret;
As 'q' is of type LLBLGenProQuery<T>. q.Count(); creates a NEW expression tree, where q is a constant. It's evaluated but all expressions are handled into NEW expressions, so 'q' is always left untouched.