NHibernate动态更新有缺点吗? [英] NHibernate dynamic-update Disadvantages?

查看:59
本文介绍了NHibernate动态更新有缺点吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有理由不对NHibernate使用dynamic-insert/dynamic-update?我问的唯一原因是,似乎我希望将其启用为默认值,而不是必须配置的内容.

Is there a reason not to use dynamic-insert/dynamic-update for NHibernate? The only reason I ask is that it seems to be something that I would want enabled as the default, not as something I would have to configure.

使用这些动态属性时,有什么要注意的地方吗?

Are there any gotchas to be aware of when using these dynamic properties?

推荐答案

对于某些实体,您可以通过动态更新来创建无效状态.假设您有一个Class,它具有一个Boolean属性A和一个逻辑相关的Integer属性B.如果属性ATrue,则属性B只能为负数,而如果属性AFalse,则属性B只能为正数.

For some entities, you may create an invalid state though dynamic updates. Let's say you've got a Class with a Boolean Property A and a logically dependent Integer Property B. If Property A is True, then Property B can only be a negative number, while if Property A is False, then Property B can only be a positive number.

比方说,两个用户都在给定的时间跨度内与此类的一个实例进行交互.首先,用户Alice和Bob都从数据库中实现了该类,其初始值为A = True和B = -50

Let's say that two users both interact with an instance of this class within a given time span. To start off, users Alice and Bob both materialize this class from the database, with the initial values of A = True and B = -50

Database   Alice       Bob
A: True    A: True     A: True
B: -50     B: -50      B: -50
VALID      VALID       VALID

用户Alice将A更改为False,将B更改为125,并将其提交到数据库.现在我们有这种情况:

User Alice changes A to False and B to 125, and commits it to the database. Now we have this situation:

Database   Alice       Bob
A: False   A: False    A: True
B: 125     B: 125      B: -50
VALID      VALID       VALID

用户Bob不会更改A,而是将B更改为-75,然后将其提交到数据库.如果启用了动态更新,则NHibernate会看到Bob仅将B更改为-75,并发出了仅编辑B值的动态更新.如果您在服务器上进行了SQL验证以防止B为负,除非A为true,则此处会出现SQL错误,但是可以说您没有在SQL表上重现所有业务逻辑.这是结果数据:

User Bob doesn't change A, but changes B to -75, then commits it to the database. If Dynamic updates are on, then NHibernate sees that Bob has only changed B to -75, and issues a dynamic update that only edits the value of B. If you had SQL validation on the server to prevent B from being negative unless A was true, you'd get a SQL error here, but let's say that you haven't reproduced all your business logic on your SQL tables. Here is the resulting data:

Database   Alice       Bob
A: False   A: False    A: True
B: -75     B: 125      B: -75
INVALID    VALID       VALID

Alice和Bob都具有有效状态,但是数据库现在处于无效状态!用户Charlie出现并尝试实现此记录:

Both Alice and Bob have valid states, but the Database is now in an invalid state! User Charlie comes along and tries to materialize this record:

Database   Alice       Bob       Charlie
A: False   A: False    A: True   A: False
B: -75     B: 125      B: -75    B: -75 
INVALID    VALID       VALID     INVALID

当NHibernate尝试设置类的新实例的B属性时,Charlie可能会从您的应用程序中收到验证错误.

Charlie would likely get a validation error from your application when NHibernate tried to set the B property of the new instance of your class.

因此,当您具有逻辑上依赖的属性时,必须采取适当的策略来避免这种情况.一种可能性是简单地为此实体启用select-before-update.这可能会导致一些额外的数据库调用,并导致性能降低.另一个是在NHibernate中利用版本控制,这意味着当Bob尝试保存他的记录时,NHibernate的插入查询不会触发任何写操作并引发陈旧的数据异常(可以妥善处理).您还可以在数据库中整理类的逻辑要求,但是随后必须谨慎确保数据库和程序随时间的推移都具有相同的整理要求,并且您将在多个地方在需求变化时进行更改,这并不总是值得的开销.

So, when you have logically dependent properties, you must have some strategy in place for avoiding this situation. One possibility is to simply enable select-before-update for this entity. This can result in some additional database calls and a little slower performance. Another is to utilize versioning in NHibernate, which would mean that when Bob tries to save his record, NHibernate's insert query would not trigger any writes and throw a stale data exception (that can be gracefully handled). You also could codify the logical requirements of your class in the database, however you'll then have to be cautious to make sure the database and the program both have the same codified requirements as time goes on, and you'll have multiple places to make changes when requirements change, which isn't always a worthwhile overhead.

因此,简而言之,在许多情况下,开发人员必须仔细处理动态更新的详细信息,这就是默认情况下不启用动态更新的原因.启用它时,请考虑对实体的部分更新是否可能导致问题,如果是,请使用我建议的一种缓解策略来防止该问题.

So in short, in many circumstances a developer must handle the details of dynamic-updates carefully, which is why it is not on by default. When you turn it on, consider if partial updates to your entity could cause problems, and if so, use one of the mitigating strategies I've recommended to protect against that issue.

这篇关于NHibernate动态更新有缺点吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆