5

エンティティ フレームワークで CodeFirst アプローチを使い始めました。

コードを実行すると、DbContext 内の DbSets に対して操作を実行できません - ProductsDb

接続文字列を確認しましたが、正しいと思いますが、操作を実行しようとするとエラーが発生します

値を null にすることはできません。パラメーター ソース。

これが ProductsDb クラスです

public class ProductsDb : DbContext
{
    public ProductsDb(string connectionString) : base(connectionString)
    {            
    }

    public ProductsDb()
    {            
    }

    public DbSet<AProduct> AProducts;
    public DbSet<BProduct> BProducts;
    public DbSet<CProduct> CProducts;
    public DbSet<DProduct> DProducts;
}

接続文字列は、app.config で次のように定義されています。

<?xml version="1.0" encoding="utf-8" ?>
  <configuration>
    <connectionStrings>
    <add name="ProductsDb" providerName="System.Data.SqlClient" 
      connectionString="Data Source=MyPC\DEV;Initial Catalog=Test;User ID=sa;
      Password=pass;" />
    </connectionStrings>
  </configuration>

エラーをスローするコードは次のとおりです。

GetAProduct(string id)
{
   AProduct aProduct = null;

   using (ProductsDb productsDb = new ProductsDb())
   {
        aProduct = (from a in productsDb.AProducts
                    where a.Id== id
                    select a).FirstOrDefault();
   }

   return aProduct;
}

すべての製品クラスは単純な古い C# クラスです。

何か助けていただければ幸いです。私は髪を抜き始めています。Sql クエリを作成するときに問題が発生することはありません。

更新: GetAProduct メソッドが変更されたコピー貼り付けエラー。

4

3 に答える 3

14

コンテキスト クラスのセットのフィールドではなくプロパティを定義する必要があります。したがって、フィールドの代わりに

public DbSet<AProduct> AProducts;

プロパティを使用する必要があります

public DbSet<AProduct> AProducts { get; set; }

Entity Framework がプロパティを検索するためです。クラスのソースを調べるDbContextと、コンストラクターで宣言されたセット プロパティを検索し、それらを初期化することがわかります。

private void DiscoverAndInitializeSets()
{
    new DbSetDiscoveryService(this).InitializeSets();
}

このセット検出サービスは、プロパティのみを検索します。

var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
var properties = 
   from p in this._context.GetType().GetProperties(flags)
   where (p.GetIndexParameters().Length == 0) && 
         (p.DeclaringType != typeof(DbContext))
   select p);

foreach(PropertyInfo info in properties)
{
    // ...
}

タイプの単純なフィールドを宣言する場合DbSet<T>、EF はその初期化をスキップし、nullコンテキストが作成された後にフィールドに値が設定されます。それが、列挙子がnull sourceここで例外をスローしていた理由です:

productsDb.AProducts.Where(a => a.Id== id)
于 2013-07-02T15:23:35.547 に答える
3

原因は異なりますが、同じエラー メッセージが表示されましinternalpublic。Sergey Berezovskiy が彼の回答で示したように、EF では、すべてのクラス メンバーを初期化するためにパブリック プロパティにする必要があります。それらを変更してpublicエラーをすぐに修正しました。

于 2014-01-31T10:02:44.080 に答える