Sam*_*Sam 16 nhibernate nhibernate-mapping
是否有理由不使用dynamic-insert/ dynamic-update用于NHibernate?我问的唯一原因是它似乎是我想要启用的默认设置,而不是我必须配置的东西.
使用这些动态属性时是否有任何问题需要注意?
tom*_*ich 28
对于某些实体,您可以通过动态更新创建无效状态.假设您Class拥有一个Boolean属性A和逻辑依赖Integer属性B.如果属性A为True,则属性B只能是负数,而如果属性A为False,则属性B只能是正数.
假设两个用户都在给定的时间跨度内与该类的实例进行交互.首先,用户Alice和Bob都从数据库中实现了这个类,初始值为A= True和B= -50
Database Alice Bob
A: True A: True A: True
B: -50 B: -50 B: -50
VALID VALID VALID
Run Code Online (Sandbox Code Playgroud)
用户Alice改变A,以False和B125,并将其提交到数据库中.现在我们遇到这种情况:
Database Alice Bob
A: False A: False A: True
B: 125 B: 125 B: -50
VALID VALID VALID
Run Code Online (Sandbox Code Playgroud)
用户Bob不会更改A,但会更改B为-75,然后将其提交到数据库.如果启用了动态更新,则NHibernate会发现Bob仅更改B为-75,并发出仅编辑其值的动态更新B.如果你在服务器上进行SQL验证以防止B被否定,除非A是真的,你会在这里得到一个SQL错误,但是假设你没有在SQL表上重现所有的业务逻辑.以下是结果数据:
Database Alice Bob
A: False A: False A: True
B: -75 B: 125 B: -75
INVALID VALID VALID
Run Code Online (Sandbox Code Playgroud)
Alice和Bob都有有效状态,但数据库现在处于无效状态!用户查理出现并尝试实现此记录:
Database Alice Bob Charlie
A: False A: False A: True A: False
B: -75 B: 125 B: -75 B: -75
INVALID VALID VALID INVALID
Run Code Online (Sandbox Code Playgroud)
当NHibernate尝试设置类的新实例的B属性时,Charlie可能会从您的应用程序中获得验证错误.
因此,当您具有逻辑依赖属性时,您必须制定一些策略来避免这种情况.一种可能性是简单地启用select-before-update该实体.这可能会导致一些额外的数据库调用和性能稍慢.另一个是在NHibernate中使用版本控制,这意味着当Bob试图保存他的记录时,NHibernate的插入查询不会触发任何写入并抛出过时的数据异常(可以优雅地处理).您还可以在数据库中编写类的逻辑要求,但是您必须小心谨慎,以确保数据库和程序在时间的推移下具有相同的编码要求,并且您将有多个位置在需求变化时进行更改,这并不总是有价值的开销.
简而言之,在许多情况下,开发人员必须仔细处理动态更新的细节,这就是默认情况下不启用的原因.当您打开它时,请考虑对您的实体进行部分更新是否会导致问题,如果是,请使用我建议的一种缓解策略来防范该问题.
动态插入和更新具有轻微的性能成本,因为NHibernate必须每次构造SQL而不是缓存它.我不知道数据库方面是否有成本.动态插入和更新非常便于进行故障排除和分析.如果我能够衡量一个有意义的性能打击,我会在开发和生产中将其打开.
我在我的NHibernate应用程序中打开它没有任何问题.我的答案是否定的,没有充分理由不使用它.
| 归档时间: |
|
| 查看次数: |
6733 次 |
| 最近记录: |