6

类似问题

实体类型 <classname> 不是当前上下文模型的一部分- 和 - EF 4.1 Code First 错误 - 实体类型 SomeType 不是当前上下文模型的一部分是类似的问题,但它们是“代码优先”的观点仅使用更简单的数据模型,并解决连接字符串和映射问题。请仔细看看这个。

症状

// HomeController.cs
public ActionResult Index()
{
    var _db = new MealsContext();

    var m = _db.Meals.ToList();
    var d = _db.Drinks.ToList();

    return View();
}

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; }
}

是的,我知道在现实世界中,肉类和蔬菜与膳食之间的关系可能是多对多的,但不要在这里纠结。

// 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; }
}

我的经验是使用 Model First 方法。EDMX 文件是在 POCO 之后构建的。

连接字符串中是映射到已解析 EDMX 资源 ( metadata=res://*/Models.MealsModels.csdl|res://*/Models.MealsModels.ssdl|res://*/Models.MealsModels.msl;) 的元数据部分。

我检查了 EDMX 文件的底层 XML,显示了概念模型和存储模型中存在的所有实体,并且所有实体都已完全映射。怎么回事?

故障排除

第一次尝试是完全摆脱存储和映射 EDMX 数据(SSDLMSL部分)。开火,现在有两个例外:

  1. 检索Meals投掷MSL, error 2062 No mapping specified for instance of the EntitySet and AssociationSet in the EntityContainer

  2. 检索Drinks继续抛出The entity type Drinkis not part of the model for the current context

引发的错误Meals是意料之中的,我对映射和存储模型进行了核对 - 检查_db表明Meals-> InternalSet->EntitySet属性是正确的,只是没有映射。

引发的错误Drinks是我卡住的地方。仔细检查_db我发现Drinks-> InternalSet->EntitySet抛出SystemInvalidOperation异常,指出实体不在模型上下文中。

以下是 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>

问题

如果DbContext具有所有DbSet属性并且正在使用一个连接字符串,其中包含一个模型的元数据,该模型的 CSDL 正确定义了实体类型Drink为什么它不是上下文的一部分?

我能看到的唯一不同Drink的是它与任何其他实体都没有关系,也没有关联......

4

2 回答 2

4

解决了。

上半场是我的疏忽。下半场……好吧,我不知道出了什么问题。这并不是真正的错误或不兼容,而是非常不方便、断断续续且难以弄清楚的事情。首先是一个摘要,然后是对那些关心的人的长度解释:

尽管有错误消息建议,但这不是概念模型 (CSDL) 的问题,而是间歇性地重新创建自身的列映射问题。

概念模型是使用 来构建的,EdmxWriter以解析DbContext其及其基础部分。

然后使用该模型生成 SQL 脚本以将模式推送到新数据库。诀窍是,数据库是Oracle。

Oracle 是个婴儿,不接受长列名。因此,必须修改生成的 EDMX 和 SQL 脚本,以构建概念模型的一部分并将其映射到截断的列名。

没什么大不了的。它工作正常。那么事情哪里出错了呢?

Oracle 不支持“代码优先”。即使它是手动完成的,EdmxWriter在 Oracle 眼中,使用 构成代码优先的方法。因此,当解析第一个 EDMX 模式时,它对布尔映射感到不满。解决方案是暂时从我的 C# 模型中删除布尔值,手动将它们添加到 EDMX 并制作 Oracle 建议的 web.config 映射(映射boolNUMBER(1,0))。

一切又变得时髦起来。但是为什么会不断重复呢?

在整个开发过程中的不同时间,协议的某些末端(C#、EDMX 或 Oracle)会发生变化。每次,似乎这些列都会自动重新映射,而我却不知道。如果从 Oracle 刷新 EDMX 模型,则映射指向不存在的 C# 属性(短列名称)。如果模型是从 C# 代码刷新的,则不会保留映射,它们会尝试映射到 Oracle 中没有的长列名。

这种方法(混合代码优先和模型优先)的遗憾是,如果我想继续管理我自己的模型并处理 Oracle 小宝贝态度所必需的定制,我必须非常小心并监控 EDMX 文件的地狱.

于 2012-12-03T20:14:53.697 回答
0

您需要为您的实体指定映射:

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; }
}

在我开始使用Entity Framework Power Tools之前,我遇到了同样的问题

使用它,您可以生成清晰的实体,如业务对象和映射类。帮助我创建惊人的数据访问层的好文章:逆向工程师代码优先

于 2012-11-29T22:40:23.383 回答