4

ここに、問題をテストして説明するための小さなコードがあります。私は3つのフィールドを持つテーブルPersonを持っています:

  • Id
  • FirstName(null許容ではありません)
  • LastName(null許容ではありません)

ループの中 :

  • 最初:最初の行を挿入します...通常、
  • 2番目:正しくないアイテムを挿入しようとしExceptionます...通常
  • 3番目:3番目の行を挿入しようとします... Exception(2番目の行と同じ)が、値は正しいです。

dataContext後に同じものを使用するために何かすることがありExceptionますか?

public class MyTestClass
{
    private readonly DataModelDataContext _dataContext;

    public MyTestClass()
    {
        _dataContext = new DataModelDataContext();
    }

    public void InsertList()
    {
        List<Person> liste = new List<Person>();
        liste.Add(new Person { FirstName = "AAA", LastName = "BBBB" });
        liste.Add(new Person { FirstName = string.Empty, LastName = null });
        liste.Add(new Person { FirstName = "CCC", LastName = "DDD" });

        foreach (var item in liste)
        {
            try
            {
                _dataContext.Persons.InsertOnSubmit(item);
                _dataContext.SubmitChanges();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
4

1 に答える 1

3

DataContext常に短命である必要があります。これを実現するには、設計をリファクタリングする必要があります。

あなたはこれらの点を考慮することができます:

  • トランザクションごとにコンテキストを使用します。このようにして、意味のある方法でコンテキストを短命にすることができます。
  • トランザクションが失敗した場合のロールバック。これには、新しいトランザクションで正しいアイテムを挿入することが含まれます。つまり、あなたは今、新鮮な異なる文脈を持っているということです。
  • トランザクションが完了するまで、このプロセスを繰り返します。
  • 繰り返しますが、完了したらコンテキストを終了することを忘れないでください。usingこれは、ステートメントを利用することで簡単に実現できます。

MSDNからのコメント

DataContextは、データベース接続を介してマップされたすべてのエンティティのソースです。取得したすべてのエンティティに加えた変更を追跡し、複数回取得したエンティティが同じオブジェクトインスタンスを使用して表されることを保証する「IDキャッシュ」を維持します。

一般に、DataContextインスタンスは、1つの「作業単位」の間持続するように設計されていますが、アプリケーションはその用語を定義します。DataContextは軽量で、作成に費用がかかりません。一般的なLINQtoSQLアプリケーションは、メソッドスコープで、または関連するデータベース操作の論理セットを表す短期間のクラスのメンバーとして、DataContextインスタンスを作成します。


デザインのリファクタリングに時間がかかる場合は、一時的に次のようにすることができます。

    public void InsertList(List<Person> people)
    {
        foreach (var person in people)
        {
            DoInsert(person); 
            // You can use the returned flag and implement the logic if desired.
            // Or let the loop move on its ways.
        }
    }

    public bool DoInsert(Person person)
    {
        try
        {
            using (DataModelDataContext dataContext = new DataModelDataContext())
            {
                dataContext.Persons.InsertOnSubmit(person);
                dataContext.SubmitChanges();
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }

これがメソッドの呼び出しInserList方法です。

    List<Person> liste = new List<Person>();
    liste.Add(new Person { FirstName = "AAA", LastName = "BBBB" });
    liste.Add(new Person { FirstName = string.Empty, LastName = null });
    liste.Add(new Person { FirstName = "CCC", LastName = "DDD" });

    InsertList(liste);
于 2012-06-20T13:40:18.327 に答える