0

このアプローチが機能しないように見えるのはなぜですか? 標準的なアプローチは何ですか?

[Database(Name = "Test")]
[Table(Name = "Order")]
public class Order
{
    [Column(Name = "ID", IsPrimaryKey = true)]
    public int ID { get; set; }

    [Column(Name = "OrderDate")]
    public DateTime OrderDate { get; set; }


    public static Order Get(int id)
    {
        Order item = null;

        try
        {
            DataContext dc = new DataContext(@"Data Source=.\sqlexpress;Initial Catalog=Test;Integrated Security=True");

            var items = from order
                        in dc.GetTable<Order>()
                        where order.ID == id
                        select order;

            item = items.FirstOrDefault<Order>();

            dc.Dispose();
        }
        catch (Exception ex)
        {
            item = null;

            throw ex;
        }

        return item;
    }

    public bool Delete()
    {
        bool success = false;

        try
        {
            DataContext dc = new DataContext(@"Data Source=.\sqlexpress;Initial Catalog=Test;Integrated Security=True");

            dc.GetTable<Order>().DeleteOnSubmit(this);

            success = true;
        }
        catch (Exception ex)
        {
            success = false;

            throw ex;
        }

        return success;
    }
}

class Program
{
    static void Main(string[] args)
    {            
        Order order = Order.Get(1);

        order.Delete();

        Console.ReadLine();
    }
}

このコードは、次の例外を生成します。

InvalidOperationException : "Cannot remove an entity that has not been attached."

私も次のことを試しました:

DataContext dc = new DataContext(@"Data Source=(local)\sqlexpress;Initial Catalog=Relationships_Test;user=;password=;Integrated Security=True");

dc.GetTable<Order>().Attach(this);
dc.GetTable<Order>().DeleteOnSubmit(this);

それもうまくいきませんでした。

4

4 に答える 4

3

削除しようとしているオブジェクトを「認識」していないメソッドで新しいを作成しDataContextています。(「エンティティが添付されていません」)Delete()Order

OrderオブジェクトをDataContext最初にアタッチします。

EDITメソッドを正常に呼び出すには、メソッド
を呼び出す必要がある場合がありitem.Detach()ます。Get(...)dc.Orders.Attach(...)Delete

EDIT 2
ああ、ちなみに: あなたのcatchハンドラーはやや役に立たない - 例外が再スローされたときに戻り値が使用されないため、基本的に何もしません。success呼び出し元のコードで例外をキャッチ -フラグを返したり、設定itemしたりする必要はありませんnull...

編集 3
もちろん、Chris が言っているようSubmitChangesに、実際に何かを行うには電話する必要があります。ただし、既にこれを行っていて、例外が発生したために尋ねただけだと思います。

于 2009-12-29T14:55:49.713 に答える
1

コンテキストにアタッチされている場合でも、コマンドを実際に実行するには、DataContext.SubmitChanges()を呼び出す必要があります。

DataContext.Dispose()を呼び出す場合は、try / catch/finally句のfinallyブロックから呼び出す必要があります。手動で呼び出す代わりに、おそらくusingステートメントを使用する必要があります。

于 2009-12-29T15:14:43.773 に答える
1

DataContext のコンテキストで作成されたオブジェクト (この場合は Order アイテム) がある場合、DataContext を Dispose すると、そのオブジェクトは孤立します。

孤立したオブジェクトをデータベースから削除するには、元の DataContext を破棄しないか、何らかの方法でオブジェクトを新しい DataContext にアタッチする必要があります (注意が必要な場合があります)。

これに対処する最も簡単な方法は、Main メソッドで DataContext を新規作成してから、main メソッドの最後で DataContext を Dispose することです (これは標準的なパターンです)。

于 2009-12-29T15:50:35.260 に答える
0

ビジネスオブジェクトに永続化メカニズムをできるだけ認識させない方が標準的だと思います。LINQtoSQLデザイナーがエンティティを作成する方法を見てください。オブジェクト自体はDataContextを認識していません。それらには、データコンテキストが変更の通知メカニズムを追加できるようにするフックと、エンティティがその存続期間中に発生する特定のイベント(作成、検証など)のコードを追加できるようにする他のフックがあります。これらは部分的なクラス実装としても作成されるため、必要に応じてコードを追加し、提供されている部分的なメソッドフックを実装できます。

より良い、より標準的な方法は、デザイナーとデザイナーが生成したクラスをORMとして使用し、部分的なクラス実装を介してコードを追加することです。または、生成されたデータコンテキストの上にリポジトリパターン(またはここ)を重ねたり、別のORM(nHibernateなど)を選択したりすることもできます。

于 2009-12-29T15:19:37.087 に答える