views:

273

answers:

2

Hello,

I have a simple Linq query below:

var seq = (from n in GetObjects() 
          select n.SomeKey)
          .Distinct()
          .Count();

This query works find with SQL Server 2005 and above.

But, this start to give headache when I hooked the EF to SQL Server 2000. Because EF is using APPLY operator which only SQL Server 2005 and above can be supported. I do not know why the hell EF is using APPLy operator instead of sub queries.

My current work around is:

var seq = (from n in GetObjects() 
              select n.SomeKey)
              .Distinct()
              .ToList()
              .Count();

But, I can forsee more problems to come. The above query is just a simple one.

Did anyone come across such issue? And how you guys work around it? Or is there a way to force EF not to use APPLY operator?

Any help will be very much appreciated.

How Lun.

A: 

I met another obstacle, which return TOP(1) of a list. I couldn't use the method above to solve this query because my list can be 10,000 records long.

I don't think this can be solved. I am so fed up with EF.

I will move back to LINQ to SQL. So so disappointed with EF.

How Lun
`Take(1)` will generate `TOP 1`, as long as you don't call `ToList` first. This is *exactly* the same in EF as with L2S. If you give up on any framework you don't understand, you won't learn anything new!
Craig Stuntz
Craig, probably you have not tried out yet. Try the below query out:var something = (from n in GetObjects() where n.Something == toSomething select n.id).Take(1).FirstOrDefault();The above query should generate a simple subquery without the need of APPLY operator, i tested with LINQPAD, work perfectly.I use the same query againts EF, use SQL Profiler, with ProviderManifestToken = 2005, it will generate a complex queries with APPLY operator.Then, If I change ProviderManifestToken to 2000, EF will throw version not supported exception.
How Lun
I am looking for idea, how to configure EF to not use APPLY operator, if this is possible.
How Lun
I can't try out `GetObjects()` because it's your code and I don't know what's inside it.
Craig Stuntz
:) just replace GetObjects() with any functions that retrieve a collection of item (Iqueryable or IEnumerable, doesnt matter) from EF model.
How Lun
A: 

The problem is that you generated your model against a 2005 (or higher) DB. So the GUI designer put a ProviderManifestToken value of 2005 or 2008 into the EDMX. This causes the SQL Server provider to generate SQL optimized for those versions. To fix this:

  1. Right click your EDMX file.
  2. Open with XML editor.
  3. Search for ProviderManifestToken
  4. Change to 2000
  5. Save and run.
Craig Stuntz
Yes, i generated the edmx againts a 2005 development db. But I have changed the value of ProviderManifestToken to 2000, to check if EF is using SQL Server 2000 compatible query. BUT.... unfortunately, EF somehow throw an exception saying the APPLY operator is supported by 2005 and above only, whenever we use complex queries which involve multiple table, agregation etc.
How Lun
OK, so the problem is actually completely different than what you said in your question! The EF is not generating the wrong SQL; rather, it is saying that it doesn't know how to express your query in a form which SQL 2000 can handle. These things do happen when you use a 10 year old DB server. The EF cannot magically make SQL 2000 gain all of the SQL verbs required to express anything you can do in LINQ. You need to either change your query or change your DB server.
Craig Stuntz
I didn't say EF is generating the wrong SQL. As an ORM, EF is "not smart enough" (probably on purpose) to not use APPLY operator when ProviderManifestToken is set to 2000. Changing DB is sometimes a mission impossible to a lot of the medium to large organizations. In my case, no. So, if you notice my question, I am asking if anyone has workaround to make my query above to work with SQL Server 2000 and EF...
How Lun