Currently, as an Entity Framework query gets translated by dotConnect (either an ESQL or a LINQ one), its "dialect" depends on the value of the ProviderManifestToken attribute from SSDL schema.
This behavior makes it impossible to use the same SSDL schema against multiple server versions (e.g. 11g and 12c).
Desired behavior would be to perform query translation based on a real version of the server in use (i.e. of the one, to which a connection is going to be established). This can be done for instance using ProviderManifestToken returned by DbProviderServices.GetProviderManifestToken(connection).
Showstopper: EF query translation and ProviderManifestToken
-
- Posts: 57
- Joined: Tue 11 Mar 2014 07:49
Re: Showstopper: EF query translation and ProviderManifestToken
This is how Entity Framework works in case of XML mapping (edmx/edml files).
ProviderManifestToken stores all needed information about the target server so that Entity Framework engine be able to create SQL in the disconnected mode without "live" connection to the database. Here is a workaround: set Metadata Artifact Processing=Copy To Output Directory for your model to generate separate mapping files (*.csdl, *.ssdl, *.msl) and use the following code:
In fact ProviderManifestToken is determined via DbProviderServices.GetProviderManifestToken(connection) "on the fly" by Entity Framework in the Code-First approach which uses attribute/fluent mapping.
ProviderManifestToken stores all needed information about the target server so that Entity Framework engine be able to create SQL in the disconnected mode without "live" connection to the database. Here is a workaround: set Metadata Artifact Processing=Copy To Output Directory for your model to generate separate mapping files (*.csdl, *.ssdl, *.msl) and use the following code:
Code: Select all
using (var conn = new OracleConnection("User Id=scott;Password=tiger;Server=orcl1120;")) {
conn.Open();
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists("DataModel1.ssdl")) {
xmlDoc.Load("DataModel1.ssdl");
}
else {
throw new FileNotFoundException("DataModel1.ssdl doesn't exist");
}
XmlNode schemaNode = xmlDoc["Schema"];
XmlAttribute providerManifestTokenAttribute = schemaNode.Attributes["ProviderManifestToken"];
// set new value of ProviderManifestToken
providerManifestTokenAttribute.Value = "Oracle, " + conn.ShortServerVersion.ToString();
// create new *.ssdl
xmlDoc.Save("DataModel1_NEWLYCREATED.ssdl");
}
// initialize context with newly added ProviderManifestToken
using(SCOTTModel.SCOTTEntities context = new SCOTTModel.SCOTTEntities()){
context.Connection.ConnectionString = "metadata=.\\DataModel1.csdl|.\\DataModel1_NEWLYCREATED.ssdl|.\\DataModel1.msl;provider=Devart.Data.Oracle;provider connection string=\"User Id=scott;Password=tiger;Server=orcl1120;Persist Security Info=True\"";
context.Connection.Open();
var depts = context.DEPTs.ToList();
}