Bagaimana cara NHibernate Projections.Max bekerja dengan tabel kosong?

Saya mencoba untuk mendapatkan nilai maksimum bidang bilangan bulat dalam sebuah tabel. Secara khusus, saya mencoba menambah kolom "Nomor Faktur" secara otomatis saat menambahkan faktur baru. Namun, saya tidak ingin ini menjadi bidang peningkatan otomatis di database, karena bidang ini dikontrol oleh pengguna -- Saya hanya mencoba menangani kasus default. Saat ini, saya sedang menggunakan

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

untuk mendapatkan nomor invoice terbesar yang sudah ada di database. Ini berfungsi dengan baik, kecuali jika belum ada faktur di database. Lalu saya mendapatkan System.ArgumentException: Nilai "" bukan bertipe "System.Int32" dan tidak dapat digunakan dalam koleksi generik ini. Mengubah ke FutureValue<int?>() tidak menyelesaikan masalah. Apakah ada cara untuk memberitahu NHibernate untuk memetakan string kosong ke null? Atau adakah cara yang lebih baik untuk mencapai tujuan saya?

Jejak tumpukan pengecualian (setidaknya bagian yang relevan) adalah

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)

person Neil    schedule 14.07.2010    source sumber


Jawaban (2)


gunakan....UniqueValue<int?>();

NH menggunakan IList non-generik dalam implementasi MultiKriterianya. Yang digunakan untuk pengelompokan FutureValue. lihat di sini untuk mengetahui alasannya List<int?> gagal menambahkan null melalui implementasi IListnya. Saya terkejut saya belum pernah mengalami hal ini sebelumnya. Hindari penggunaan tipe nilai nullable dengan Future atau MultiCriteria.

person dotjoe    schedule 14.07.2010
comment
FutureValue‹int?› memiliki masalah yang sama. Saya bermaksud menambahkannya ke dalam pertanyaan, tetapi lupa memasukkannya ke dalam rentang kode, sehingga generiknya hilang--Maaf! Ada ide lain? - person Neil; 15.07.2010
comment
aneh, database mana yang kamu gunakan? Tipe data apa itu InvoiceNumber? - person dotjoe; 15.07.2010
comment
Juga, di mana tepatnya pengecualian ini dilempar? Apakah Anda menggunakan IList non-generik di mana saja? - person dotjoe; 15.07.2010
comment
Saya menggunakan SQL Server (Khususnya tahun 2005, tetapi ini terjadi pada tahun 2000 dan (menurut saya) 2008 juga). InvoiceNumber adalah int. Saya telah menambahkan pengecualian pada pertanyaan, jika itu membantu. - person Neil; 16.07.2010

Dengan API QueryOver:

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

jika tidak ada yang dikembalikan, itu nol, jika tidak, berikan hasilnya sebagai numerik

person jenson-button-event    schedule 28.09.2011