I have a pretty basic table in SQL Server (dual key, no foreign keys). I have generated mapping code using SQLMetal. I have also extended the auto generated partial class so I can implement IEquatable. The problem is that once I implement IEquatable, I lose the ability to update records using my SQLMetal generated classes. When submitting changes I get the following exception:
Incorrect syntax near the keyword 'WHERE'
The sample code below illustrates the problem. It runs fine until implementing 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();
This is my implementation for IEquatable (auto generated by 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;
}
}
}
Take a look at the query that prints out in the output window. When IEquatable is implemented, the SET clause is empty (and causes the exception to be thrown):
UPDATE [dbo].[TestTable]
SET
WHERE ([PrimaryKey1] = @p0) AND ([PrimaryKey2] = @p1) AND ([TheValue] = @p2)
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [123]
-- @p1: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Red]
-- @p2: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [8dedfdca-84e9-4b7a-9268-4bbdde2e9ad2]
Here is the same output without IEquatable implemented:
UPDATE [dbo].[TestTable]
SET [TheValue] = @p3
WHERE ([PrimaryKey1] = @p0) AND ([PrimaryKey2] = @p1) AND ([TheValue] = @p2)
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [123]
-- @p1: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Red]
-- @p2: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [8f6e72ee-f89e-40f3-830f-18e8b4b40f9e]
-- @p3: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [1ecaff9d-d460-4f3e-b35d-138ddeb2fb63]
Is this behavior expected? Is there a way to get around it?