【问题标题】:How does NHibernate Projections.Max work with an empty table?NHibernate Projections.Max 如何处理空表?
【发布时间】:2010-07-14 18:40:46
【问题描述】:

我正在尝试获取表中整数字段的最大值。具体来说,我试图在添加新发票时自动增加“InvoiceNumber”字段。但是,我不希望它成为数据库中的自动增量字段,因为它是由用户控制的——我只是想处理默认情况。现在,我正在使用

session.CreateCriteria<Invoice>()
        .SetProjection(Projections.Max("InvoiceNumber"))
        .FutureValue<int>();

获取数据库中已有的最大发票编号。这很好用,除非数据库中已经没有发票。然后我得到一个 System.ArgumentException: The value "" is not of type "System.Int32" and cannot be used in this generic collection.更改为FutureValue&lt;int?&gt;() 并没有解决问题。有没有办法告诉 NHibernate 将空字符串映射到 null?还是有更好的方法来完全实现我的目标?

异常的堆栈跟踪(至少相关部分)是

NHibernate.HibernateException: Error executing multi criteria : [SELECT max(this_.[InvoiceNumber]) as y0_ FROM dbo.[tblInvoice] this_;
SELECT this_.ID as ID647_0_, this_.[NHVersion] as column2_647_0_, this_.[Description] as column3_647_0_, this_.[DiscountPercent] as column4_647_0_, this_.[DiscountDateDays] as column5_647_0_, this_.[PaymentDueDateDays] as column6_647_0_, this_.[Notes] as column7_647_0_, this_.[DiscountDateMonths] as column8_647_0_, this_.[PaymentDueDateMonths] as column9_647_0_, this_.[DiscountDatePeriod] as column10_647_0_, this_.[DiscountDateMonthlyDay] as column11_647_0_, this_.[DiscountDateMonthlyDayDay] as column12_647_0_, this_.[DiscountDateMonthlyDayMonth] as column13_647_0_, this_.[DiscountDateMonthlyThe] as column14_647_0_, this_.[DiscountDateMonthlyTheDOW] as column15_647_0_, this_.[DiscountDateMonthlyTheMonth] as column16_647_0_, this_.[DiscountDateMonthlyTheWeek] as column17_647_0_, this_.[PaymentDueDatePeriod] as column18_647_0_, this_.[PaymentDueDateMonthlyDay] as column19_647_0_, this_.[PaymentDueDateMonthlyDayDay] as column20_647_0_, this_.[PaymentDueDateMonthlyDayMonth] as column21_647_0_, this_.[PaymentDueDateMonthlyThe] as column22_647_0_, this_.[PaymentDueDateMonthlyTheDOW] as column23_647_0_, this_.[PaymentDueDateMonthlyTheMonth] as column24_647_0_, this_.[PaymentDueDateMonthlyTheWeek] as column25_647_0_ FROM dbo.[tblTermsCode] this_;
] ---> System.ArgumentException: The value "" is not of type "System.Int32" and cannot be used in this generic collection.
Parameter name: value
   at System.ThrowHelper.ThrowWrongValueTypeArgumentException(Object value, Type targetType)
   at System.Collections.Generic.List`1.VerifyValueType(Object value)
   at System.Collections.Generic.List`1.System.Collections.IList.Add(Object item)
   at NHibernate.Impl.MultiCriteriaImpl.GetResultsFromDatabase(IList results)

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    使用....UniqueValue&lt;int?&gt;();

    NH 在其 MultiCriteria 实现中使用非泛型 IList。用于 FutureValue 批处理。请参阅 here 了解为什么 List&lt;int?&gt; 无法通过其 IList 实现添加 null 。我很惊讶我以前从未遇到过这种情况。避免在 Future 或 MultiCriteria 中使用可为空的值类型。

    【讨论】:

    • FutureValue 有同样的问题。我打算在问题中添加它,但忘记将它放在代码跨度中,所以泛型丢失了 - 对不起!还有其他想法吗?
    • 奇怪,你用的是哪个数据库? InvoiceNumber 是什么数据类型?
    • 另外,这个异常到底是在哪里抛出的?您是否在任何地方使用非泛型 IList?
    • 我正在使用 SQL Server(特别是 2005 年,但它也发生在 2000 年和(我认为)2008 年)。 InvoiceNumber 是一个整数。如果有帮助,我已将例外添加到问题中。
    【解决方案2】:

    使用 QueryOver API:

    Session.QueryOver<T>()
          .Select(Projections.Max<Statistic>(s => s.PeriodStart))
          .SingleOrDefault<object>();
    

    如果没有返回 null,否则将结果转换为数字

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多