[英]EntitySet System.InvalidOperationException - “the entity type is not part of the model for the current context”
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. 实体类型<classname>不是当前上下文的模型的一部分 - 并且 - EF 4.1 Code First错误 - 实体类型SomeType不是当前上下文的模型的一部分是类似的问题,但它们是“代码优先”透视只有更简单的数据模型,并解决连接字符串和映射问题。 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: 检索Drinks
集合时会抛出异常:
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. 我的经验是使用Model First方法。 The EDMX file was built then the POCOs. EDMX文件是在POCO之后构建的。
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;
). 在连接字符串中是映射到解析的EDMX资源的元数据部分( 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. 我检查了EDMX文件的基础XML,显示了Conceptual和Store模型中存在的所有实体,并且所有实体都已完全映射。 WTF? WTF?
The first tried was to completely get rid of the store and mapping EDMX data (the SSDL
and MSL
sections). 第一个尝试是完全摆脱存储和映射EDMX数据( SSDL
和MSL
部分)。 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
. 检索Meals
会引发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
. 检索Drinks
继续抛出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. 预计由Meals
抛出的错误,我修改了映射和存储模型 - 检查_db
向我显示Meals
- > InternalSet
- > EntitySet
属性是正确的,只是没有映射。
The error thrown by Drinks
is where I am stuck. Drinks
引发的错误是我被困住的地方。 Examining _db
closer shows me that Drinks
-> InternalSet
-> EntitySet
throws the SystemInvalidOperation
exception that states the entity is not in the model context. 检查_db
告诉我Drinks
- > InternalSet
- > EntitySet
会抛出SystemInvalidOperation
异常,该异常表明实体不在模型上下文中。
Here's what the EDMX's CSDL looks like in XML format: 以下是EDMX的CSDL在XML格式中的样子:
<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? 如果DbContext
具有所有DbSet
属性并且正在使用连接字符串,该连接字符串包含CSDL正确定义实体类型Drink
的模型的元数据, 为什么在地狱中它不是上下文的一部分?
The only thing different about Drink
that I can see is that it is not related to any other entities, and has no associations... 我能看到的唯一与Drink
不同的是它与任何其他实体无关,并且没有关联......
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. 概念模型是使用EdmxWriter
用于解析DbContext
及其底层部分。
The model then was used to generate SQL scripts to push the schema to a new database. 然后,该模型用于生成SQL脚本以将架构推送到新数据库。 The trick is, the database is Oracle. 诀窍是,数据库是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. 因此,必须修改生成的EDMX和SQL脚本,以构建概念模型的部分并将其映射到截断的列名称。
Not really a big deal. 没什么大不了的。 It works fine. 它工作正常。 So where did things go wrong? 那么事情出了什么问题?
Oracle does not support "code first". Oracle不支持“代码优先”。 And even though it was done manually, using the EdmxWriter
constitutes a code-first approach in Oracle's eyes. 即使它是手动完成的,使用EdmxWriter
构成了Oracle眼中的代码优先方法。 So when the first EDMX schema was parsed, it bitched about boolean mappings. 因此,当解析第一个EDMX模式时,它就是关于布尔映射的。 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)
). 解决方案是暂时从我的C#模型中删除bool
,手动将它们添加到EDMX并进行Oracle建议的web.config映射(将bool
映射到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. 在整个开发过程的不同时间,协议的某些目标--C#,EDMX或Oracle - 都会被更改。 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). 如果从Oracle刷新EDMX模型,则映射指向不存在的C#属性(短列名称)。 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. 如果从C#代码刷新模型,则不会保留映射,并且它们会尝试映射到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. 如果我想继续管理我自己的模型并处理Oracle小宝贝态度所需的自定义,那么这种方法有点糟糕( 首先是混合代码和模型优先 ),我必须非常小心并监控EDMX文件的地狱。
You need to specify mappings for your entities: 您需要为实体指定映射:
public class MealsContext: DbContext
{
public MealsContext() : base("ConnectionString")
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// mappings
}
public DbSet<Meal> Meals{ get; set; }
public DbSet<Meat> Meats{ get; set; }
public DbSet<Vegetable> Vegetables { get; set; }
public DbSet<Drink> Drinks{ get; set; }
}
I had the same problem until I started using Entity Framework Power Tools 在我开始使用Entity Framework Power Tools之前,我遇到了同样的问题
Using it you can generate clear entities like a business objects and mapping classes. 使用它,您可以生成明确的实体,如业务对象和映射类。 Good article that helped me to create amazing data access layer: Reverse Engineer Code First 帮助我创建出色的数据访问层的好文章: 逆向工程师代码优先
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.