I use Linq-to-SQL/XML and I consider my application to be 3 tier. The difference between a pre-Linq application is that now the data access layer is much small and lighter which is actually a very good thing!
In my old DAL I would have had methods like:
public virtual int CountCustomersInCountry(string country) {
// Plug in raw SQL.
}
public virtual List<Customer> GetCustomersInCountry(string country) {
// Plug in raw SQL.
}
public virtual int CountCustomersForDepartment(string department) {
// Plug in raw SQL.
}
public virtual List<Customer> GetCustomersForDepartment(string department) {
// Plug in raw SQL.
}
etc. etc. ad-infinitum
I now have the following sort of methods:
public virtual int Count(Expression<Func<T, bool>> where) {
// Plug in Linq-to-SQL DataContext here.
}
public virtual T Get(Expression<Func<T, bool>> where) {
// Plug in Linq-to-SQL DataContext here.
}
public virtual List<T> Get(Expression<Func<T, bool>> where, string orderByField, int offset, int count) {
// Plug in Linq-to-SQL DataContext here.
}
To call the new DAL methods and with a little bit of help from DynamicLinq I use:
int countryCount = Count(c => c.Country == country);
List<Customer> customers = Get(c => c.Country == country, "inserted", 0, 25);
int departmentCount = Count(c => c.Department == department);
List<Customer> customers = Get(c => c.Department == department, "inserted", 0, 25);
And all thats before you get onto Adds, Updates and Deletes which become single line calls with Linq2SQL! My DAL now consists of 10 methods where as previously it was easy to get up to 20 to 30 methods for each object my DAL was looking after! I'd highly recommend trying to get your head around it as it really will save you a lot of code.
I would use First()
when I know or expect the sequence to have at least one element. In other words, when it is an exceptional occurrence that the sequence is empty.
Use FirstOrDefault()
when you know that you will need to check whether there was an element or not. In other words, when it is legal for the sequence to be empty. You should not rely on exception handling for the check. (It is bad practice and might hurt performance).
Finally, the difference between First()
and Take(1)
is that First()
returns the element itself, while Take(1)
returns a sequence of elements that contains exactly one element.
Best Answer
I would avoid serializing whenever you have the opportunity to just pass the data as a strongly typed class. And that is what you're going to have to do. I believe when .Net 4.0 comes out you will be able to pass vars, but until then, try returning your query as an IEnumerable instead of a var when you need to pass it to another function.
IE: