views:

327

answers:

2

I am using Entity Framework with MySQL. The following query results an error:

var foobar = ctx.ArticleBase.OfType<ActicleSpecial>().Include("CreatedBy.Image.Location").ToList();

Error: "OUTER APPLY is not supported by MySQL" I also get the "CROSS APPLY is not supported by MySQL" on a little different query.

I have the following datamodel: alt text

Except the Image entity have Location entity (one to many relation) named Location relation and UserBase have Image relation instead of UserSpecial.

Why do I get this error? How to avoid this error? Is it possible?

+2  A: 

If this error is coming from MySQL one of two things have happened:

  1. You haven't configured the provider correctly.
  2. There is a bug in your EF provider.

If this error is coming from your MySQL EF provider, then one of two things have happened:

  1. You haven't configured the provider correctly.
  2. There is a limitation in your EF provider.

SQL is generated by the provider. You can configure server-version-specific SQL generation via the ProviderManifestToken attribute in EDMX. This is how you tell the provider not to use SQL features which older server versions don't support.

It's possible that some MySQL storage engines support SQL features which others do not. In this case, the provider would need to either use a common subset of features supported by most engines or use ProviderManifestToken to allow you to choose.

However, it's also possible that a buggy provider simply returns incorrect SQL. If this is the case then you must either find an update or avoid queries which touch the bug.

Update: Based on @Devart's answer, it seems that this is a limitation of the provider, which is designed in due to limitations of MySQL. The EF will produce an ADO.NET canonical command tree. It is the provider's responsibility to translate this to SQL. If the EF returns a cross/outer apply node in the CCT, it seems that Devart has not found a way to translate this to SQL which MySQL can handle. So either MySQL is just not up to the task of supporting all EF queries, or someone who is a MySQL expert (not me!) needs to show Devart how to produce MySQL-compatible SQL which can properly return rows for the cross/outer apply CCT nodes.

Craig Stuntz
Sorry, Craig, you are wrong. This is neither configuration error, nor the bug in MySQL EF provider.
Devart
Please read the article you linked. It says no such thing.
Craig Stuntz
Here is a quote:"In some cases the query pipeline might produce a Transact-SQL statement that contains CROSS APPLY and/or OUTER APPLY operators. Because some backend providers, including versions of SQL Server earlier than SQL Server 2005, do not support these operators, such queries cannot be executed on these backend providers."This is the Peter's case. We had contacted Microsoft on this issue and the answer was negative - this functionality is not to be changed.
Devart
@Devart: The EF does not produce T-SQL, *period.* It produces an ADO.NET Canonical Command tree The SqlClient *provider* is what produces T-SQL. It's certainly true that using the SQL Client provider with non-SQL Server DBs would be a problem.could be
Craig Stuntz
We are not arguing about this point, Craig. It is correct.
Devart
+1  A: 

This is an Entity Framework internal architecture feature. Sometimes it generates queries not supported by providers other than SQL Server. More information is available here at MSDN.

Devart
That is wrong. The article you link describes "Known Issues in the .NET Framework Data **Provider for SQL Server (SqlClient)** for the Entity Framework)." (Emphasis added.) The simple fact is that **all** SQL generation in the EF is done by the provider, *not* the EF itself.
Craig Stuntz
So what is true? If provider generate a SQL, then obviously there is a bug in you provider to MySQL. Why then you use Cross Apply or Outer Apply with MySQL? How should I write a query to avoid this problem? To I have to set something in Devart connector?
Peter Stegnar
SQL is generated from the expression tree given by EF query pipeline. If the tree already contains OUTER APPLY, there is no way to get rid of it in the provider.
Devart
The tree would contain the `System.Data.SqlClient.SqlGen.SqlGenerator.OuterApplyOp` node, *not* the T-SQL Statement! If the provider translates that into SQL which the server cannot support, that's a bug in the provider. If there is no possible way to transliterate the CCT into SQL the server can support, it should not indicate this by producing SQL which the server cannot support! I'm wondering if you're trying to re-use the `System.Data.SqlClient.SqlGen` types? There's nothing wrong with doing this, as far as it goes, but it's hard-coded for T-SQL. That is *not* an EF limitation!
Craig Stuntz
Sorry; I got the namespace wrong in my cut and paste. But the point is the same; it's a tree node, not a T-SQL statement.
Craig Stuntz
You are right again, Craig. Devart provider throws NotSupportedException iin the case when the OuterApply node is met by translator and no SQL is generated. However, we insist that this limitation is an EF one.
Devart
OK. The question made it sound as if he was getting this error from MySQL. But in light of what you said, it seems it's coming from the provider. If that's the case it changes some of the subtleties of my answer, so I'll update for clarity.
Craig Stuntz