Joh*_*las 6 .net c# sql insert-update linq-to-sql
这很奇怪...之前已经完成了很多次更新,但无法发现为什么会有所不同.虽然我现在使用.net 4.0 - 但我怀疑它的L2S实现中的一个错误.它不像是一个奇怪而精彩的应用程序.虽然我很确定这个代码在我使用RC时有效.
我还设法通过使用以下信息从头开始构建项目来重现此错误.
这里的问题是L2S生成的更新语句在set语句中没有字段.我已经尝试检查pk是否已设置(只是为什么我认为在其中需要ervery字段的原因)并且还读取了其他dbml属性的aroudn.我一直在使用linq2Sql大约1年,从来没有遇到过问题.我仍然认为我只是有一个巨大的脑屁.
注意:我已经清理了equals和GetHashCode方法来删除一些字段 - 此后问题仍然存在.我还没有清理SQL.
我有一个来自dbml的客户端类,我添加了一个名为update的方法
public partial class Client : ICopyToMe<Client>
Run Code Online (Sandbox Code Playgroud)
CopyToMe方法继承自接口
public interface ICopyToMe<T>
{
void CopyToMe(T theObject);
}
Run Code Online (Sandbox Code Playgroud)
该类还覆盖了getHashCode
public override int GetHashCode()
{
int retVal = 13 ^ ID ^ name.GetHashCode();
return retVal;
}
Run Code Online (Sandbox Code Playgroud)
和平等
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;
}
Run Code Online (Sandbox Code Playgroud)
部分类中的更新方法
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();
}
Run Code Online (Sandbox Code Playgroud)
CopytoMe方法
public void CopyToMe(Client theObject)
{
ID = theObject.ID;
name = theObject.name;
}
Run Code Online (Sandbox Code Playgroud)
我带了一个被选中的客户端,更改了它的名字,然后调用了这个更新方法.生成的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
Run Code Online (Sandbox Code Playgroud)
我不知道为什么这不起作用......用过这种方式
选择对象 - >将字段设置为新值 - >提交所选对象
模式多次,没有这个问题.dbml也没有明显的错误 - 尽管这可能是一个错误的陈述
有任何想法吗?
这个问题使得看起来我将不得不回到ADO.Net,这会让我感到难过.
好的,在与一些非常有帮助的微软人员进行讨论后,我找到了这个问题的答案。
Linq 使用哈希码在哈希表中索引其集合。这意味着哈希码函数只需要对唯一标识对象的字段起作用。
在这种情况下,Hash 只能作用于 ID 列。因此,对于具有相同主键的记录,即使数据不同,GetHashCode 也始终会返回相同的值。
另一方面,Equals 可以测试更多的字段 - 即它的测试比 GetHashCode 比较更具体。
如果您使 GetHashCode 函数覆盖的字段多于主键,那么 linq2sql 将失去对对象的跟踪,因此行为会非常奇怪。
| 归档时间: |
|
| 查看次数: |
321 次 |
| 最近记录: |