views:

243

answers:

3

Hi,

If I design my db layer so I can swap it between a linq-to-sql or nhibernate implementation, I have to code against an interface.

This means the return type between both linq and nhibernate have to be the same i.e. List etc.

Is the list type the same?

A: 

NHibernate returns IList by default for collections, and a lot of linq expressions don't work on them, unfortunately. I'm not sure if there is a way of changing the NHibernate return type, as I haven't really looked into it.

Jimmeh
+2  A: 

If you encapsulate your database access, for example using the repository pattern, you could have the repositories implement a common interface and have the methods return the type you choose to use as return type, such as IEnumerable(T) or IList(T).

Since IList(T) implements IEnumerable(T) there is no problem in that direction. If you have an IEnumerable(T) you can use the ToList() extension method on IEnumerable(T) to get List(T). IQueryable(T) implements IEnumerable(T) to ToList() works fine in that case as well.

Something like this:

public interface IFooRepository
{
    IList<Foo> GetAll();
    // ...
}

public class NHibernateFooRepository : IFooRepository
{
    //...

    public IList<Foo> GetAll()
    {
        return Session.CreateCriteria(typeof(Foo)).List<Foo>();
    }
}


public class LinqToSqlFooRepository : IFooRepository
{
    //...

    public IList<Foo> GetAll()
    {
        var foos = from Foo f in context.Foos select f;
        return foos.ToList();
    }
}
Erik Öjebo
+1  A: 

IIRC, unless you'd want to use your db layer without LINQ query comprehensions (using the repository pattern), you should take a look at LINQ to NHibernate; in that case, you'd pretty much code against IQueryable<T> results, which should translate most of the time. (Though you should really test this upfront, because every provider is different in its LINQ support.)

However, 1-* relations on your entity types will probably not share the same type by default (it's usually EntitySet<T> in LINQ-to-SQL, and IList<T> in NHibernate), but if you can force both LINQ-to-SQL and NHibernate to use IList<T> or IEnumerable<T> for such relations, this should work as well.

If you're only after compile time compatibility, the distinction between the various collection types should not be much of a problem, as long as you stick to the generic ones. For instance, if your NHibernate mapping uses IList<T> and LINQ-to-SQL uses EntitySet<T>, just stick to the IList<T> methods, and you'll be safe.

Just watch out for lazy and eager loading differences of each framework.

Ruben