Time for another progress report, and this one's a biggie :)
Barring a couple of pretty minor things that won't take much fixing, all the original Linq tests have now been ported over to the new provider and are all passing. That means the new provider is now (from the perspective of the tests, at least) in better shape that the version 1 provider. It can do everything the original provider could, plus a whole bunch more. A couple of example queries that now work just fine are:
from e in db.Employees
from et in e.Territories
where e.Address.City == "Seattle"
select new {e.FirstName, e.LastName, et.Region.Description};
from c in db.Customers
join o in db.Orders on c.CustomerId equals o.Customer.CustomerId into orders
select new {c.ContactName, OrderCount = orders.Average(x => x.Freight)};
from o in db.Orders
from p in db.Products
join d in db.OrderLines on new {o.OrderId, p.ProductId} equals new {d.Order.OrderId, d.Product.ProductId}
into details
from d in details
select new {o.OrderId, p.ProductId, d.UnitPrice}
from c in db.Customers
join o in db.Orders on c.CustomerId equals o.Customer.CustomerId
group o by c into x
select new { CustomerName = x.Key.ContactName, Order = x }
(ignore whether those queries make any real sense, it's just the form of them that matters)
So, more importantly, what doesn't work? Well, out of the tests that we've currently got, not a huge amount. Some important areas that are missing are:
from e in db.Employees
join o in db.Orders on e equals o.Employee into ords
from o in ords.DefaultIfEmpty()
select new {e.FirstName, e.LastName, Order = o};
This is a fairly widely used construct, so is close to top of the list for future supportfrom c in db.Customers
join o in db.Orders on c.CustomerId equals o.Customer.CustomerId into ords
let z = c.Address.City + c.Address.Country
from o in ords
select new {c.ContactName, o.OrderId, z};
Again, this is quite high on the TODO list.I've also got a number of TODOs, but mainly cleanup rather than functional, plus I need to work through the error handling to ensure that any queries that are passed in that the provider can't handle are rejected gracefully rather than just barfing (which is the likely case right now).
The only gotcha that I know of is a query that runs just fine but doesn't necessarily return the correct number of results. Specifically, queries like this:
from user in db.Users
select new
{
user.Name,
RoleName = user.Role.Name
};
Right now, this generates a join to the Role table, so any users that don't have a role are not returned. This differs from Linq to SQL where a left join is generated, giving a null RoleName for any users without a role. I believe the Linq to SQL implementation to be correct - the above query doesn't explicitly have any form of filtering (where clause, join clause etc), so you should get back all the users in the database. This one is top of the list, and hopefully will be fixed soon (it's not hard, I've just run out of time!).
In summary, I'm getting pretty happy with the state of the provider and think that it's now ready for general usage - although there are still some important query forms to support, I think there's sufficient there now to do useful work. If you've got good test coverage, then I'd even be happy for it to go live. If you don't have good coverage, then don't come crying to me :)
Of course, this is all in the trunk, so anyone wanting to play either needs to get the trunk source and build it, or take the much easier option of having Horn do the work. Horn builds the trunk on a daily basis, so look for a package built after around 2300GMT on the 16/12/2009 (the package URL on Horn has the datetime stamp in it, so it's pretty easy to spot).
I'm on holiday for the next couple of weeks, and will only have intermittent internet access. However, ping me either by email or twitter with comments / bugs / suggestions, and I'll do my best to reply. Normal service (whatever that is) will return around Jan 4th.