Bug with .ssdl generation
Posted: Thu 09 Apr 2015 23:17
There is a bug with how the .ssdl is generated. When a property of type uniqueidentifier has its Store Generate Pattern set to Identity the .ssdl does not get generated with a StoreGeneratedPattern="Identity" for said property.
This is a big problem because the .ssdl file is one of three that is included as meta-data and used by the Entity Framework to map things out. The net result of this bug is that the Entity Framework will not know that this particular property is supposed to get its value from the server and instead will attempt to provide the value from the client which in the case of a Guid winds up being '00000000-0000-0000-0000-000000000000' and you get a "Violation of PRIMARY KEY constraint" exception.
Here's an example of the .ssdl generated that has a property who's Store Generate Pattern set to Identity but is missing the StoreGeneratedPattern="Identity" in the output. If I manually add this to the .ssdl the "Violation of PRIMARY KEY constraint" exception goes away and Entity Framework once again knows that this property is supposed to get its value from the server.
This is a big problem because the .ssdl file is one of three that is included as meta-data and used by the Entity Framework to map things out. The net result of this bug is that the Entity Framework will not know that this particular property is supposed to get its value from the server and instead will attempt to provide the value from the client which in the case of a Guid winds up being '00000000-0000-0000-0000-000000000000' and you get a "Violation of PRIMARY KEY constraint" exception.
Here's an example of the .ssdl generated that has a property who's Store Generate Pattern set to Identity but is missing the StoreGeneratedPattern="Identity" in the output. If I manually add this to the .ssdl the "Violation of PRIMARY KEY constraint" exception goes away and Entity Framework once again knows that this property is supposed to get its value from the server.
Code: Select all
<EntityType Name="AnonymousUser">
<Key>
<PropertyRef Name="UserId" />
</Key>
<Property Name="UserId" Type="uniqueidentifier" Nullable="false" devart:DefaultValue="newsequentialid()" />
<Property Name="LastVisited" Type="datetime2" Nullable="false" devart:DefaultValue="sysutcdatetime()" />
<Property Name="CreatedOn" Type="datetime2" Nullable="false" devart:DefaultValue="sysutcdatetime()" />
<Property Name="IpAddress" Type="nvarchar" Nullable="false" MaxLength="50" />
</EntityType>
Code: Select all
static string GetConnectionString()
{
var connectionBuilder = new SqlConnectionStringBuilder();
connectionBuilder.UserID = AppSettings.Instance.ConnectionSettings.DbUserName;
connectionBuilder.Password = AppSettings.Instance.ConnectionSettings.DbPassword;
connectionBuilder.InitialCatalog = AppSettings.Instance.ConnectionSettings.DbName;
connectionBuilder.DataSource = AppSettings.Instance.ConnectionSettings.Server;
EntityConnectionStringBuilder ecsb = new EntityConnectionStringBuilder();
ecsb.Provider = "System.Data.SqlClient";
ecsb.ProviderConnectionString = connectionBuilder.ConnectionString;
ecsb.Metadata = GetMetaData();
return ecsb.ConnectionString;
}
static string GetMetaData()
{
var modelPrefix = "MyApp.Data.Models.MyContext";
var metaData = new StringBuilder();
metaData.Append("res://*/" + modelPrefix + ".csdl|");
metaData.Append("res://*/" + modelPrefix + ".ssdl|");
metaData.Append("res://*/" + modelPrefix + ".msl");
return metaData.ToString();
}