Posts tagged Entity Framework
This weeks side-project was the creation of an ontology store using Entity Framework 4. An ontology store stores axioms consisting of Subject, Predicate, Object which are usually serialized as RDF, OWL, N3, … Whereas there’s lots of details about these serialization formats, the actual mechanics of how to store and manipulate them was somewhat harder to come by. Nevertheless, after much experimentation I came up with an Entity Model that can store Quads (Subject, Predicate, Object and Meta) or Quins (Subject, Predicate, Object, Meta, Graph). The addition of Meta allows one Axiom to reference another. The addition of Graph allows the store to be segmented making it easy to import some N3 or RDF into a graph, then flush that graph if it is no longer needed or if a newer version becomes available.
The store is currently hooked up to an Euler reasoner that can reason against it, lazily fetching just the necessary records from the SQL database that backs the Entity Model.
Here’s the EDMX showing how I modeled the Ontology Store:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable
Today’s cryptic Entity Framework message …
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
The reason for this was a simple override to GetHashCode(). Entity Framework seems somewhat pedantic about how hash codes work.
Today I tried creating a two-level hierarchy using Entity Framework 4 but using the same discriminator column for both layers of the hierarchy. It seems you cannot do this but instead must have a separate column for each layer of the hierarchy. Makes some sense but the error message wasn’t very helpful.
I have a table-per-hierarchy model, one abstract class (Node), a column that differentiates the sub-classes (NodeType), and three sub-classes (NodeClass, NodeProperty, NodeIndividual) with conditions (NodeType=1, 2, 3), it’s working just fine.
I now want to add another sub-class which itself has three sub-classes. So I create the new sub-class marking it abstract (NodeLiteral), I create the three derived types inheriting from it (NodeiteralInt, NodeLiteralDouble, NodeLiteralDateTime) and add conditions on them based on the same discriminator column used in the first level of inherited classes (NodeType=101,102,103).
When I compile I get:-
Error 3032: Problem in mapping fragments starting at lines … (classes) … are being mapped to the same rows in table Node. Mapping conditions can be used to distinguish the rows that these types are mapped to.
Since I DO have mapping conditions that are distinct for each of these classes the error message is somewhat confusing.
If I add another column and use that as the discriminator for the second level of inheritance it works.
So if you are trying to model a two or more layer hierarchy in EF don’t try to use a single column for all your conditions, create a column for each layer of the hierarchy instead.
System.Data.UpdateException: A value shared across entities or associations is generated in more than one location. Check that mapping does not split an EntityKey to multiple store-generated columns
This Visual Studio 2010 RC bug is really causing grief. If you see the error message above, check your EDMX file. Visual Studio may have kindly inserted an extra
into your EDMX file on a child table for the association back to the parent table.
For example, this …
<EntityType Name="ExceptionRecordData"> <Key> <PropertyRef Name="ExceptionDataUID" /> </Key> <Property Name="ExceptionDataUID" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="ExceptionUID" Type="bigint" Nullable="false" /> <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="32" /> <Property Name="Value" Type="nvarchar" Nullable="false" MaxLength="128" /> </EntityType>
becomes this … after a simple Update operation
<EntityType Name="ExceptionRecordData"> <Key> <PropertyRef Name="ExceptionDataUID" /> </Key> <Property Name="ExceptionDataUID" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="ExceptionUID" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="32" /> <Property Name="Value" Type="nvarchar" Nullable="false" MaxLength="128" /> </EntityType>
Note how it has added an extra StoreGeneratedPattern=”Identity” on the ExceptionUID property. I hope this gets fixed soon.
If you experience this problem, here’s the link to up-vote it:- https://connect.microsoft.com/data/feedback/details/540058
Update: Microsoft has confirmed that this will be fixed in the released version of Visual Studio 2010 – see comments. Thanks!
If you encounter this error, make sure your constructor is calling the base constructor for an ObjectContext and passing the EntityContainer name.
System.ArgumentException: The EntityContainer name could not be determined. The provided EntitySet name must be qualified by the EntityContainer name, such as'EntityContainerName.EntitySetName', or the DefaultContainerName property mustbe set for the ObjectContext.
I recently tried the latest release of .NET 4.0 to see what improvements have been made to the Entity Framework. Overall it’s good news BUT I’m disappointed to see that things that worked in Linq-To-Sql still don’t work in Linq-To-Entities. For example, simple DateTime manipulation like checking the DayOfWeek doesn’t work.
In Linq-To-Sql you could use an expression like this:
var dayOfWeekCondition = (dt => dt.DayOfWeek == dayOfWeek);
But in Linq-To-Entities you have to use this expression:
int dow = (int)dayOfWeek + 1; // SQL Day of week
var dayOfWeekCondition = (dt => SqlFunctions.DatePart(“weekday”, dt) == dow);
AND by doing that you have now bound your expression to working only with SQL Server. If you want an expression that works with CLR types you’ll need to build that separately.
If anyone builds the code to automatically convert an Expression tree to SqlFunction calls from regular C# expressions do let me know!
[Update: The final release of .NET 4 includes fixes for most of these issues]