6

これは奇妙です...完了した更新は何度も前に行われましたが、これが異なる理由を見つけることができません。私は現在.net 4.0を使用していますが、L2S実装のバグではないかと疑っています。これは、それの奇妙で素晴らしいアプリケーションではありません。RCを使用している間、このコードが機能したことはかなり確信していますが。

また、以下の情報を使用してプロジェクトをゼロから構築することで、このエラーを再現することもできました。

ここでの問題は、L2S によって生成された update ステートメントの set ステートメントにフィールドがないことです。私はpkが設定されていることを確認しようとしました(whereにすべてのフィールドが必要だと思う唯一の理由です)、他のdbmlプロパティも読んでみました。私は linq2Sql を約 1 年間使用していますが、問題が発生したことはありません。

注: equals メソッドと GetHashCode メソッドをクリーンアップして、いくつかのフィールドを削除しました。この後も問題は解決しません。ただし、SQLをクリーンアップしていません。

updateというメソッドを追加したdbmlのクライアントクラスがあります

public partial class Client :  ICopyToMe<Client>

CopyToMe メソッドはインターフェイスから継承されます

   public  interface ICopyToMe<T>
    {
        void CopyToMe(T theObject);
    }

また、クラスには getHashCode がオーバーライドされています

public override int GetHashCode()
{
    int retVal = 13 ^ ID ^ name.GetHashCode();
    return retVal;
}

そして等しい

public override bool Equals(object obj)
{
    bool retVal = false;
    Client c = obj as Client;
    if (c != null)
        if (c.ID == this.ID && c._name == this._name)
            retVal = true;
    return retVal;
} 

部分クラスの update メソッド

 public void UpdateSingle()
        {          
            L2SDataContext dc = new L2SDataContext();
            Client c = dc.Clients.Single<Client>(p => p.ID == this.ID);
            c.CopyToMe(this);
            c.updatedOn = DateTime.Now;

            dc.SubmitChanges();
            dc.Dispose();
                        }

CopytoMe メソッド

 public void CopyToMe(Client theObject)
        {
            ID = theObject.ID;
            name = theObject.name;                
        }

選択されたクライアントを取得し、その名前を変更してから、この更新メソッドを呼び出します。生成されたSQLは次のとおりです

exec sp_executesql N'UPDATE [dbo].[tblClient]
SET 
WHERE ([ID] = @p0) AND ([name] = @p1) AND ([insertedOn] = @p2) AND ([insertedBy] = @p3) AND ([updatedOn] = @p4) AND ([updatedBy] = @p5) 
AND ([deletedOn] IS NULL) AND ([deletedBy] IS NULL) AND (NOT ([deleted] = 1))',N'@p0 int,@p1 varchar(8000),@p2 datetime,@p3 int,@p4 
datetime,@p5 int',@p0=103,@p1='UnitTestClient',@p2=''2010-05-17 11:33:22:520'',@p3=3,@p4=''2010-05-17 11:33:22:520'',@p5=3

これが機能しない理由がわかりません...この種の

オブジェクトを選択 -> フィールドを新しい値に設定 -> 選択したオブジェクトを送信

パターンは何度もあり、この問題はありませんでした。また、dbml には明らかな問題はありません。ただし、これはおそらく誤った記述です。

何か案は?

この問題により、ADO.Net に戻らなければならないように見えてしまい、悲しくなります。

4

2 に答える 2

1

非常に親切なマイクロソフトの人々との議論の後、私はこの問題に対する答えを見つけました。

Linq はハッシュ コードを使用して、ハッシュ テーブル内のコレクションにインデックスを付けます。つまり、ハッシュ コード関数は、オブジェクトを一意に識別するフィールドに対してのみ機能する必要があります。

この場合、ハッシュは ID 列でのみ機能します。そのため、GetHashCode は、データが異なっていても、同じ主キーを持つレコードに対して常に同じ値を返します。

一方、Equals はより多くのフィールドにわたってテストできます。つまり、そのテストは GetHashCode 比較よりも具体的です。

GetHashCode 関数が主キーよりも多くのフィールドをカバーするようにすると、linq2sql はオブジェクトの追跡を失い、非常に奇妙な動作をします。

于 2010-05-20T09:45:10.980 に答える
0

その正確な UPDATE ステートメントが (SET 引数なしで) データベースに送信された場合、LINQ to SQL にバグが見つかりました。コードを .NET 4.0 で試してみて、それでも失敗する場合は、Microsoft Connect サイトにバグを送信してください。

于 2010-05-17T11:27:51.773 に答える