c# - Linq2Sql - 尝试更新但 sql 中的 Set 语句为空

标签 c# .net sql linq-to-sql insert-update

这很奇怪……之前完成了多次更新,但无法找出为什么会有所不同。 虽然我现在使用的是 .net 4.0 - 但我怀疑它在 L2S 实现中存在错误。这并不是它的一个奇怪而美妙的应用。虽然我相当确定这段代码在我使用 RC 时有效。

我还设法通过使用以下信息从头开始构建项目来重现此错误。

这里的问题是L2S生成的update语句在set语句中没有字段。我已经尝试检查 pk 是否已设置(我认为在 where 中需要 ervery 字段的唯一原因)并且还阅读了其他 dbml 属性。我已经使用 linq2Sql 大约 1 年了,从来没有遇到过问题..我仍然认为我只是在放一个巨大的脑屁。

注意:我已经清理了 equals 和 GetHashCode 方法以删除一些字段 - 此后问题仍然存在。不过,我还没有清理 SQL。

我有一个来自 dbml 的客户端类,我添加了一个名为更新的方法

public partial class Client :  ICopyToMe<Client>

CopyToMe方法继承自一个接口(interface)

   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;
} 

分部类中的更新方法

 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,这会让我很难过。

最佳答案

好的,在与一些非常乐于助人的微软人员讨论后,我找到了这个问题的答案。

Linq 使用哈希码在哈希表中索引其集合。 这意味着哈希码函数只需要作用于唯一标识对象的字段。

在这种情况下,哈希只能作用于 ID 列。 因此,GetHashCode 将始终为具有相同主键的记录返回相同的值,即使它们的数据不同也是如此。

另一方面,Equals 可以测试更多的字段 - 即它的测试比 GetHashCode 比较更具体。

如果您使 GetHashCode 函数覆盖的字段多于主键,那么 linq2sql 将失去对对象的跟踪,因此会表现得非常奇怪。

关于c# - Linq2Sql - 尝试更新但 sql 中的 Set 语句为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2848442/

相关文章:

c# - 使用 Task.WhenAll 与 BlockingCollection 产生的无限任务

c# - C#中的选择语句

c# - 你将如何声明 DLL 导入签名?

php - 我可以免受 SQL 注入(inject)攻击吗?

sql - 内连接临时表

c# - 如何从我的 Windows 商店应用程序连接到 SQL Azure 数据库表?

c# - 多值字典?

c# - 多个套接字连接

c# - 如何在 TableLayoutPanel 中动态设置单元格颜色?

php - 列出两个单独表中 ID 匹配的记录