草庐IT

c# - NHibernate Session.Flush() 在没有发生更新时发送更新查询

coder 2023-07-09 原文

我有一个 NHibernate session 。在此 session 中,我执行了 1 个操作,即运行此代码以获取列表:

public IList<Customer> GetCustomerByFirstName(string customerFirstName)
{
return _session.CreateCriteria(typeof(Customer))
    .Add(new NHibernate.Expression.EqExpression("FirstName", customerFirstName))
    .List<Customer>();
}

我在 HttpRequest 的末尾调用 Session.Flush(),我得到了一个 HibernateAdoException。 NHibernate 将更新语句传递给数据库,并导致外键冲突。如果我不运行 flush,请求将毫无问题地完成。这里的问题是我需要适当的刷新以防其他 session 中发生更改,因为此代码在其他区域重复使用。我可能缺少其他配置设置吗?


这是异常的代码:

[SQL: UPDATE CUSTOMER SET first_name = ?, last_name = ?, strategy_code_1 = ?, strategy_code_2 = ?, strategy_code_3 = ?, dts_import = ?, account_cycle_code = ?, bucket = ?, collector_code = ?, days_delinquent_count = ?, external_status_code = ?, principal_balance_amount = ?, total_min_pay_due = ?, current_balance = ?, amount_delinquent = ?, current_min_pay_due = ?, bucket_1 = ?, bucket_2 = ?, bucket_3 = ?, bucket_4 = ?, bucket_5 = ?, bucket_6 = ?, bucket_7 = ? WHERE customer_account_id = ?]

没有显示正在传递的参数。

最佳答案

每当您处理 NHibernate 时,请务必小心 NULLable 字段。如果您的字段在数据库中是 NULLable,请确保相应的 .NET 类也使用 Nullable 类型。否则,会发生各种奇怪的事情。症状通常是 NHibernate 将尝试更新数据库中的记录,即使自从您从数据库中读取实体后您没有更改任何字段。

以下顺序解释了为什么会发生这种情况:

  1. NHibernate 使用 ADO.NET 从数据库中检索原始实体的数据
  2. NHibernate 构造实体并设置其属性
  3. 如果数据库字段包含 NULL,则该属性将设置为其类型的默认值:
    • 引用类型的属性将被设置为空
    • 整数和浮点类型的属性将被设置为0
    • boolean 类型的属性将被设置为 false
    • DateTime 类型的属性将设置为 DateTime.MinValue
    • 等等
  4. 现在,当提交事务时,NHibernate 将属性的值与它从 DB 读取的原始字段值进行比较,并且由于字段包含 NULL 但属性包含非空值,NHibernate 认为属性脏,并强制更新实体。

这不仅会影响性能(每次检索实体时都会额外往返数据库并进行额外更新),而且还可能导致难以解决 DateTime 列的错误。事实上,当 DateTime 属性被初始化为其默认值时,它被设置为 1/1/0001。当这个值被保存到 DB 时,ADO.NET 的 SqlClient 不能将它转换成有效的 SqlDateTime 值,因为最小的 SqlDateTime 可能是 1/1/1753!!!

最简单的解决方法是使类属性使用 Nullable 类型,在本例中为“DateTime?”。或者,您可以通过实现 IUserType 及其 Equals 方法来实现自定义类型映射器,正确地将 DbNull.Value 与您的值类型的任何默认值进行比较。在我们的例子中,当将 1/1/0001 与 DbNull.Value 进行比较时,Equals 需要返回 true。实现一个全功能的 IUserType 并没有那么难,但它确实需要 NHibernate 琐事知识,所以如果您选择这样做,请准备好进行一些实质性的谷歌搜索。

关于c# - NHibernate Session.Flush() 在没有发生更新时发送更新查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34852/

有关c# - NHibernate Session.Flush() 在没有发生更新时发送更新查询的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  3. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  4. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  5. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  6. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  7. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  8. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  9. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  10. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

随机推荐