2012-10-24 60 views
1

我一直在努力使用表适配器和数据集访问接入数据库的项目。我很接近完成,从Visual Studio运行代码分析,并将其与一些错误想出了约需要实现上,我使用这些方法的特定类的IDisposable。虽然我已经看过关于使用dispose方法或使用使用块的一些不同的事情,但我不确定如何使其工作。创建数据集和表适配器,由全班使用全局变量,许多班级将呼吁其他班也将使用不同的表适配器和数据集。我试图创建一个Dispose方法,但我不知道什么时候调用它,我想知道,如果它被称为在错误的时间将它弄坏我的计划。这里是我需要实现IDisposable类的一个样本:什么是正确的方式来处理表适配器和数据集?

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并使用自动生成的方法,把所有的表适配器和在那里要处理的数据集,但我该如何使用它以及在哪里?

感谢您的帮助

克雷格

+2

您可能需要先卸下NotImplementedException。 –

回答

1

正如在其他的答案中提到的正确方法使用实现IDisposable是withing using块如下目标:

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

我想做些什么,虽然指出的是正确的实施的IDisposable模式。请注意,MSDN article for the IDisposable interface上有一个完整的示例。

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)不应该抛出异常。

+0

这是正确和完整的模式,但在这里它是严重的矫枉过正。 –

+0

@亨克是的,在这种情况下,你可能会失去'isDisposed'变量并合并两个'Dispose'方法,因为这个类没有封装任何非托管资源。这就是说,如果你要教某人如何做某事,你应该给他们全面的照片。假设OP将在这里得出答案并将其应用于更广泛范围的类似问题并非不合理。更不用说其他用户可能会偶然发现这个线程,可能需要这个答案的全部范围。 –

+0

好吧,所以我在需要它的所有类上实现了Idisposible,并且尝试使用一个使用语句,如使用(var nr = new NewRecipe()){newRecipe = new NewRecipe(newRecipeInfo,newRatingNum,ingredientList);}现在我得到使用行上的编译器错误,因为此类不包含使用0参数的构造函数,这是正确的。我是否还需要在这个类中添加一个新的构造函数? –

2

正常模式:

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

但几个音符在这里:

  • 了IDisposable接口上的DataSet和DataAdapter是虚设,跳过它们时不会损失太多。
  • 你的类具有资源库和域对象的双重作用。考虑将它分成两类。
+0

并且将放置在创建NewRecipe对象的方法中? –

+0

不确定你的意思,我看到一个构造函数和一个CreateNewRecipe。但是使用应该在这个类之外。 –

+0

我认为我进入这个项目越来越深刻,我意识到有很多东西可以学习,即存储库和域对象。我从一个拥有5个winforms所有这些方法的项目中拿出这个项目,并试图将它分解为更多可重用的代码。 –

0

正确的使用方法是using。只是不要把它在你的手中 -

using(DataAdapter ratingTableAdapter = new DataAdapter()) 
{ 

} 

ratingTableAdapter将得到处置,一旦代码出来using块。

+0

所以我把使用的语句放在实际创建newRecipe对象的代码中,并且在NewRecipe类中删除了public void Dispose()方法?这是我迷路的地方。 –

相关问题