0

SQL Server にかなり基本的なテーブルがあります (デュアル キー、外部キーなし)。SQLMetal を使用してマッピング コードを生成しました。IEquatable を実装できるように、自動生成された部分クラスも拡張しました。問題は、IEquatable を実装すると、SQLMetal で生成されたクラスを使用してレコードを更新できなくなることです。変更を送信すると、次の例外が発生します。

キーワード「WHERE」付近の構文が正しくありません

次のサンプル コードは、問題を示しています。IEquatable を実装するまで問題なく動作します。

var connection = "Your connection string";
var dbInsert = new DBTest(connection);
var recordToInsert = new TestTable()
{
    PrimaryKey1 = 123,
    PrimaryKey2 = "Red",
    TheValue = Guid.NewGuid().ToString(),
};
dbInsert.TestTable.InsertOnSubmit(recordToInsert);
dbInsert.SubmitChanges();

var dbEdit = new DBTest(connection);
dbEdit.Log = Console.Out;
var ti1 = dbEdit.TestTable.Single(x => x.PrimaryKey1 == 123 && x.PrimaryKey2 == "Red");
ti1.TheValue = Guid.NewGuid().ToString();
dbEdit.SubmitChanges();

これは IEquatable の私の実装です (ReSharper によって自動生成されます):

public partial class TestTable : IEquatable<TestTable>
{
    public bool Equals(TestTable other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return _PrimaryKey1 == other._PrimaryKey1 && string.Equals(_PrimaryKey2, other._PrimaryKey2) && string.Equals(_TheValue, other._TheValue);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((TestTable)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = _PrimaryKey1;
            hashCode = (hashCode * 397) ^ (_PrimaryKey2 != null ? _PrimaryKey2.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (_TheValue != null ? _TheValue.GetHashCode() : 0);
            return hashCode;
        }
    }
}

出力ウィンドウに出力されるクエリを見てください。IEquatable が実装されている場合、SET 句は空です (例外がスローされます)。

UPDATE [dbo].[TestTable]
SET
WHERE ([PrimaryKey1] = @p0) AND ([PrimaryKey2] = @p1) AND ([TheValue] = @p2)
-- @p0: Input Int (Size = -1; Prec = 0; スケール = 0) [123]
-- @p1: 入力 NVarChar (サイズ = 4000; 精度 = 0; スケール = 0) [赤]
-- @p2: 入力 NVarChar (サイズ = 4000; 精度 = 0; スケール= 0) [8dedfdca-84e9-4b7a-9268-4bbdde2e9ad2]

以下は、IEquatable を実装していない同じ出力です。

UPDATE [dbo].[TestTable]
SET [TheValue] = @p3
WHERE ([PrimaryKey1] = @p0) AND ([PrimaryKey2] = @p1) AND ([TheValue] = @p2)
-- @p0: Input Int (サイズ = -1; 精度 = 0; スケール = 0) [123]
-- @p1: 入力 NVarChar (サイズ = 4000; 精度 = 0; スケール = 0) [赤]
-- @p2: 入力 NVarChar (サイズ = 4000) ; Prec = 0; Scale = 0) [8f6e72ee-f89e-40f3-830f-18e8b4b40f9e]
-- @p3: 入力 NVarChar (Size = 4000; Prec = 0; Scale = 0) [1ecaff9d-d460-4f3e-b35d-138ddeb2fb63 ]

この動作は予期されたものですか? それを回避する方法はありますか?

4

1 に答える 1

1

GetHashCode() メソッドをオーバーライドすると、変更を追跡する DataContext の機能が損なわれることが判明しました。GetHashCode オーバーライドを削除すると、問題が解決しました。

于 2016-09-01T19:34:46.723 に答える