6

同様の質問

エンティティタイプ<classname>は現在のコンテキストのモデルの一部ではありません-そして-EF4.1コードファーストエラー-エンティティタイプ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; }
}

私の経験は、モデルファーストの方法論を使用したことです。EDMXファイルが作成されてからPOCOが作成されました。

接続文字列には、解析されたEDMXリソースにマップするメタデータセクションがあります(metadata=res://*/Models.MealsModels.csdl|res://*/Models.MealsModels.ssdl|res://*/Models.MealsModels.msl;)。

EDMXファイルの基礎となるXMLを調べたところ、ConceptualモデルとStoreモデルに存在するすべてのエンティティが示され、すべてが完全にマップされています。WTF?

トラブルシューティング

SSDL最初に試みたのは、ストアとマッピングEDMXデータ(およびMSLセクション)を完全に取り除くことでした。発射してください、そして今、2つの例外があります:

  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にすべてのプロパティがあり、DbSetCSDLがエンティティタイプを正しく定義しているモデルのメタデータを含む接続文字列を使用している場合、なぜそれがコンテキストの一部ではないのですか?Drink

私が見ることができる唯一の違いDrinkは、それが他のエンティティとは関係がなく、関連付けがないことです...

4

2 に答える 2

4

解決しました。

前半は私の見落としでした。後半…まあ、何が悪かったのか一言も言えません。これは実際にはバグや非互換性ではありませんが、非常に不便で、断続的で、理解するのが難しいものです。最初に要約し、次に気になる人のための長さの説明:

エラーメッセージの提案にもかかわらず、それは概念モデル(CSDL)の問題ではなく、断続的にそれ自体を再作成する列マッピングの問題でした。

概念モデルは、とその基礎となる部分EdmxWriterを解析するためにを使用して構築されました。DbContext

次に、このモデルを使用してSQLスクリプトを生成し、スキーマを新しいデータベースにプッシュしました。秘訣は、データベースがOracleであるということです。

Oracleは赤ちゃんであり、長い列名を受け入れません。そのため、生成されたEDMXおよびSQLスクリプトを変更して、概念モデルの一部を構築し、切り捨てられた列名にマップする必要がありました。

それほど大したことではありません。正常に動作します。では、どこで問題が発生したのでしょうか。

Oracleは「コードファースト」をサポートしていません。そして、それが手動で行われたとしてもEdmxWriter、オラクルの目には、を使用することはコードファーストのアプローチを構成します。そのため、最初のEDMXスキーマが解析されたとき、ブールマッピングについて愚痴をこぼしました。解決策は、C#モデルからboolを一時的に削除し、それらを手動でEDMXに追加して、Oracleが提案するweb.configマッピング(boolにマッピング)を作成することNUMBER(1,0)でした。

すべてが再びグルーヴィーです。しかし、なぜそれが再発し続けるのですか?

開発プロセス全体のさまざまな時点で、契約の一部の端(C#、EDMX、またはOracle)が変更されます。そして毎回、列が自動的に再マップされたようで、私は気づいていませんでした。EDMXモデルがOracleから更新された場合、マッピングは存在しなかった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 に答える