The entity type <classname> is not part of the model for the current context -and- EF 4.1 Code First error - The entity type SomeType is not part of the model for the current context are similar questions but they are "code first" perspective only, with much simpler data models, and address connection string and mapping issues. Please look closely at this one.
// HomeController.cs
public ActionResult Index()
{
var _db = new MealsContext();
var m = _db.Meals.ToList();
var d = _db.Drinks.ToList();
return View();
}
Exception is thrown retrieving the Drinks
collection:
The entity type Drink is not part of the model for the current context.
// Meal.cs
public class Meal
{
public int Id { get; set; }
public string Stuff { get; set; }
public virtual ICollection<Meat> Meats { get; set; }
public virtual ICollection<Vegetable> Vegetables { get; set; }
}
// Meat.cs
public class Meat
{
public int Id { get; set; }
public string Name { get; set; }
public int MealId { get; set; }
}
// Vegetable.cs
public class Vegetable
{
public int Id { get; set; }
public string Name { get; set; }
public int MealId { get; set; }
}
// Drink.cs
public class Drink
{
public int Id { get; set; }
public string Name { get; set; }
}
Yes, I know in the real world the relationship between Meat and Vegetable with Meals would likely be Many-to-Many but don't get hung up on it here.
// MealsContext.cs
public class MealsContext: DbContext
{
public MealsContext() : base("ConnectionString")
public DbSet<Meal> Meals{ get; set; }
public DbSet<Meat> Meats{ get; set; }
public DbSet<Vegetable> Vegetables { get; set; }
public DbSet<Drink> Drinks{ get; set; }
}
My experience was in using a Model First methodology. The EDMX file was built then the POCOs.
In the connection string is the metadata section that maps to the parsed EDMX resources (metadata=res://*/Models.MealsModels.csdl|res://*/Models.MealsModels.ssdl|res://*/Models.MealsModels.msl;
).
I examined the underlying XML of the EDMX file shows all entities present in Conceptual and Store models, and all are fully mapped. WTF?
The first tried was to completely get rid of the store and mapping EDMX data (the SSDL
and MSL
sections). Fire away, and now there are two exceptions:
Retrieving Meals
throws MSL, error 2062 No mapping specified for instance of the EntitySet and AssociationSet in the EntityContainer
.
Retrieving Drinks
continues to throw The entity type Drinkis not part of the model for the current context
.
The error thrown by Meals
is expected, I nuked the mappings and store model -- examining _db
shows me that Meals
-> InternalSet
-> EntitySet
property is correct, just not mapped.
The error thrown by Drinks
is where I am stuck. Examining _db
closer shows me that Drinks
-> InternalSet
-> EntitySet
throws the SystemInvalidOperation
exception that states the entity is not in the model context.
Here's what the EDMX's CSDL looks like in XML format:
<edmx:ConceptualModels>
<Schema ...>
<EntityContainer Name="MealsContext" annotation:LazyLoadingEnabled="true">
<EntitySet Name="Meals" EntityType="Models.Meal" />
<EntitySet Name="Meats" EntityType="Models.Meat" />
<EntitySet Name="Vegetables" EntityType="Models.Vegetable" />
<EntitySet Name="Drinks" EntityType="Models.Drink" />
<!-- AssociationSets here for the FKs -->
</EntityContainer>
<!-- All are present, but here's the culprit Drink -->
<EntityType Name="Drink">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" Nullable="false" MaxLength="200" FixedLength="false" Unicode="true" />
</EntityType>
<!-- Associations here -->
</Schema>
</edmx:ConceptualModels>
If the DbContext
has all the DbSet
properties and is consuming a connection string that includes metadata for a model who's CSDL correctly defines the entity type Drink
, why in the hell is it not part of the context?
The only thing different about Drink
that I can see is that it is not related to any other entities, and has no associations...
Solved.
The first half was my oversight. The second half... well I don't have a word for what was wrong. It is not really a bug, or incompatibility, but something very inconvenient, intermittent and hard to figure out. First a summary, and then the length explanation for those who care:
The conceptual model was built using the EdmxWriter
to parse the DbContext
and its underlying pieces.
The model then was used to generate SQL scripts to push the schema to a new database. The trick is, the database is Oracle.
Oracle is a baby and does not accept long column names. So the generated EDMX and SQL Scripts had to be modified to build and map parts of the conceptual model to truncated column names.
Not really a big deal. It works fine. So where did things go wrong?
Oracle does not support "code first". And even though it was done manually, using the EdmxWriter
constitutes a code-first approach in Oracle's eyes. So when the first EDMX schema was parsed, it bitched about boolean mappings. The solution was to temporarily remove the bools from my C# models, add them to the EDMX manually and make the web.config mapping Oracle suggests (mapping bool
to NUMBER(1,0)
).
Everything is groovy again. But why does it keep reoccurring?
At different times throughout the development process some ends of the agreement - either C#, EDMX, or Oracle - are altered. And each time, it seems the columns were automatically remapped and I was unaware. If the EDMX model was refreshed from Oracle, the mappings were pointing to C# properties that didn't exist (the short column names). If the model was refreshed from C# code the mappings were not preserved and they attempted to map to long column names that weren't in Oracle.
The bummer with this approach (sort of hybrid code first and model first) is if I want to continue managing my own models and handle customizations necessary for Oracle's little baby attitude, I have to be very careful and monitor the hell out of the EDMX file.