最近,我一直在阅读LINQ,以开始实施它,关于它如何生成令我困扰的UPDATE查询有一个特别的问题。
使用SQLMetal或对象关系设计器自动创建实体代码,显然所有表的所有字段都将获得属性UpdateCheck.Always,这意味着对于每个UPDATE和DELETE查询,我将获得如下SQL语句:
UPDATE table SET a = 'a' WHERE a='x' AND b='x' ... AND z='x', ad infinitum
现在,叫我一个纯粹主义者,但这对我来说似乎是非常低效的,即使它不是没有效率的,但无论如何还是觉得这是一个坏主意。我知道提取操作将由集群主键完成,因此这并不慢,但是SQL仍需要在此之后检查每个字段以确保其匹配。
当然,在某些非常敏感的应用程序中,这样的功能可能会有用,但对于典型的Web应用程序(例如Stack Overflow),它似乎是UpdateCheck.WhenChanged将是一个更合适的默认值,我个人更喜欢UpdateCheck.Never,因为LINQ将仅更新更改的实际字段,而不是所有字段,并且在大多数实际情况下,第二个人编辑总会赢。
这确实意味着,如果两个人在读取该行与触发UPDATE之间的短时间内设法编辑同一行的同一字段,则不会触发发现的冲突。但实际上这是非常罕见的情况。当两个人更改同一件事时,我们可能要防备的一件事不会被此捕获,因为他们无论如何都不会在同一时间单击“提交”,因此在第二个DataContext发生时不会发生冲突。读取并更新记录(除非显示页面时DataContext保持打开状态并存储在Session中,否则类似的严重错误主意)。
但是,在极少数情况下,如果发生这种情况,我真的很想不时在代码中获取异常。
所以我的第一个问题是,我是否相信这一点? (同样,对于“典型” Web应用程序,而不是银行应用程序)
我是否缺少某些原因为什么拥有UpdateCheck.Always默认为明智的选择?
我的第二个问题是,我可以文明地改变它吗?有没有办法告诉SQLMetal或ORD要设置哪个UpdateCheck属性?
我试图避免这种情况,我必须记住要运行一个工具,我必须使它使用一些正则表达式并直接编辑文件中的所有属性,因为显然在某些时候我们将运行更新数据库后,SQLMetal将不会运行此工具,并且所有代码都将以非常微妙的方式破坏,而在开发人员进行测试时可能无法找到。
有什么建议?
战争的故事非常受欢迎,我很乐于从其他人的经验中学到东西。
非常感谢你!
最佳答案
好吧,回答第一个问题-我同意你的看法。我不是这种“内置”乐观并发的忠实拥护者,尤其是如果您有时间戳列或任何在更新发生后不能保证相同的字段时,尤其如此。
为了解决第二个问题-我不知道有什么方法可以替代SqlMetal的默认方法(UpdateCheck = Always),我们最终编写了一个为适当的列设置UpdateCheck = Never的工具。我们正在使用一个批处理文件来调用SqlMetal,然后再运行该工具。
哦,虽然我想到了这一点-还是发现SqlMetal还将关系建模为将外键设置为null而不是“ Delete On Null”(特别是对于联接表),这也是一种享受。我们也必须使用相同的后生成工具来适当地设置它们。
关于linq - LINQ冲突检测:设置UpdateCheck属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/685930/