1

私は、テーブル アダプターとデータセットを使用してアクセス データベースにアクセスするプロジェクトに取り組んできました。私は完成に近づいており、Visual Studio からコード分析を実行しましたが、これらのメソッドを使用する特定のクラスに IDisposable を実装する必要があるというエラーが発生しました。dispose メソッドの使用や using ブロックの使用について、これについていくつかの異なることを見てきましたが、これを機能させる方法がよくわかりません。データセットとテーブル アダプターは、クラス全体で使用されるグローバル変数として作成されます。多くのクラスは、異なるテーブル アダプターとデータセットを使用する他のクラスを呼び出します。Dispose メソッドを作成しようとしましたが、呼び出すタイミングがわかりません。間違ったタイミングで呼び出すと、プログラムがクラッシュするのではないかと考えています。

   using System;
   using System.Collections.Generic;
   using System.Linq;
    using System.Text;

 namespace recipeDataBase 
 {
     class NewRecipe : IDisposable
     {
         recipiesNewDataSet recipeDataSet = new recipiesNewDataSet();
         recipiesNewDataSetTableAdapters.RecipeTableAdapter recipeTableAdapter = new      recipiesNewDataSetTableAdapters.RecipeTableAdapter();
    recipiesNewDataSetTableAdapters.RecipeIngredientTableAdapter recipeIngredientTableAdapter = new recipiesNewDataSetTableAdapters.RecipeIngredientTableAdapter();
    recipiesNewDataSetTableAdapters.RatingTableAdapter ratingTableAdapter = new recipiesNewDataSetTableAdapters.RatingTableAdapter();
    recipeDataBase.recipiesNewDataSetTableAdapters.IngredientTableAdapter ingredientTableAdapter = new recipiesNewDataSetTableAdapters.IngredientTableAdapter();
    private RecipeInfo newRecipe;
    private RatingNum originalRatingNum;
    private RatingNum newRating;
    private RecipeInfo originalRecipe;
    private string[] ingredients;

    public NewRecipe(RecipeInfo incommingNewRecipe, RatingNum IncommingNewRating, string[] incommingIngredients)
    {
        newRecipe = incommingNewRecipe;
        newRating = IncommingNewRating;
        ingredients = incommingIngredients;
        CreateNewRecipe();
        UpdateNewRecipe();
    }
    public void CreateNewRecipe()
    {
        originalRatingNum = new RatingNum();
        originalRecipe = new RecipeInfo();
        originalRatingNum.cookingTime = 0;
        originalRatingNum.easeOfCooking = 0;
        originalRatingNum.familyRating = 0;
        originalRatingNum.healthRating = 0;
        originalRatingNum.userRating = 0;

        ratingTableAdapter.Fill(recipeDataSet.Rating);
        ratingTableAdapter.Insert(originalRatingNum.userRating, originalRatingNum.familyRating, originalRatingNum.healthRating, originalRatingNum.easeOfCooking, originalRatingNum.cookingTime);
        Query getNewRecipeNumbers = new Query();
        int newRatingNumber = getNewRecipeNumbers.newRatingNum();



        originalRatingNum.ratingNum = newRatingNumber;
        newRating.ratingNum = newRatingNumber;
        newRecipe.ratingNum = newRatingNumber;
        originalRecipe.recipeName = "newRecipe";
        originalRecipe.nationality = "newRecipe";
        originalRecipe.recipeEvent = "newRecipe";
        originalRecipe.source = "newRecipe";
        originalRecipe.type = "newRecipe";
        originalRecipe.servings = "0";
        originalRecipe.ratingNum = newRatingNumber;


        recipeTableAdapter.Fill(recipeDataSet.Recipe);
        recipeTableAdapter.Insert(originalRecipe.recipeName, originalRecipe.nationality, originalRecipe.recipeEvent, originalRecipe.source, originalRecipe.type, originalRecipe.servings, originalRecipe.ratingNum); 
        int newRecipeNum = getNewRecipeNumbers.newRecipeNum();
        newRecipe.recipeNum = newRecipeNum;
        originalRecipe.recipeNum = newRecipeNum;
        recipeDataSet.AcceptChanges();
    }

    public void UpdateNewRecipe()
    {
        UpdateRatingNum updateRatingNum = new UpdateRatingNum(originalRatingNum, newRating);
        UpdateRecipe updateRecipe = new UpdateRecipe(newRecipe, originalRecipe);

        UpdateIngredients updateIngredients = new UpdateIngredients(ingredients);
        UpdateRecipeIngredient updateRecpeIngredients = new UpdateRecipeIngredient(ingredients, newRecipe.recipeNum);
        recipeDataSet.AcceptChanges();

    }


    public void Dispose()
    {
        ratingTableAdapter.Dispose();
        recipeTableAdapter.Dispose();
        recipeTableAdapter.Dispose();
        ingredientTableAdapter.Dispose();
        recipeDataSet.Dispose();
        throw new NotImplementedException();
    }
}

}

ご覧のとおり、Idisposable を実装し、自動的に作成されたメソッドを使用して、そこにすべてのテーブル アダプターとデータセットを配置して破棄しましたが、どのように使用し、どこで使用するのでしょうか?

助けてくれてありがとう

クレイグ

4

3 に答える 3

2

通常のパターン:

using (var nr = new NewRecipe() )
{
   ...
}

ただし、ここにいくつかの注意事項があります。

  • DataSet と DataAdapter の IDisposable インターフェイスはダミーなので、それらをスキップしてもあまり失うことはありません。
  • クラスには、リポジトリとドメイン オブジェクトの二重の役割があります。2 つのクラスに分けることを検討してください。
于 2012-10-24T13:05:36.280 に答える
1

他の回答で述べたように、実装するオブジェクトを使用IDisposableする正しい方法は、次のように using ブロック内にあります。

using (var recipe = new NewRecipe())
{
    //put your code that uses recipe here
}

私が指摘したいのは、IDisposable パターンの正しい実装です。IDisposable インターフェイスの完全な例が MSDN の記事にあることに注意してください。

class Recipe : IDisposable
{
    bool isDisposed = false;
    TableAdapter myDisposableMember;

    public void Dispose()
    {
        Dispose(true);
        GC.SupressFinalize(this);
    }

    public virtual Dispose(bool isDisposing)
    {
        if (!isDisposed) //only clean up once
        {
            //clean up unmanaged resource here
            //in this case we don't have any

            //clean up managed resources (IE those that implemetn IDisposable only if
            //Dispose() was called (not the case when invoked during finalisation)
            if (isDisposing)
            {
                if(myDisposableMember == null)
                {
                    myDisposableMember.Dispose()
                    myDisposablemember = null;
                }
            }

            //mark this instance as cleaned up
            isDisposed = true;
        }
    }

    //if our class has any unmanaged resources you implement a destructor to guarantee
    //that they're freed. We don't have any here so we don't implement it.
    //~Recipe()
    //{
    //    Dispose(false);
    //}
}

また、ファイナライズ中に例外をスローしてはならないことに注意してください (IE: ~Recipe())。したがってDispose(bool)、決して例外をスローしないでください。

于 2012-10-24T13:38:23.123 に答える
0

正しい使い方はusing. 手に取らないでください -

using(DataAdapter ratingTableAdapter = new DataAdapter())
{

}

コードが using ブロックから出ると、ratingTableAdapterは破棄されます。

于 2012-10-24T13:09:37.127 に答える