2011-11-09 45 views
1

我面臨一個顯然很奇怪的問題(我必須做錯了什麼,只是找不到我的錯誤!)。當某些POCO保存到數據庫中時,什麼都不會發生。當相同的POCO更改了某些屬性時,會話刷新期間會出現InvalidCastException,並且行從不更新。以下是詳細信息:更新nhibernate對象拋出InvalidCastException(但保存它不)

我有以下類中聲明:

namespace Data 
{ 
    public class Picture 
    { 
     public virtual int picid { get; set; } 
     public virtual int width { get; set; } 
     public virtual int height { get; set; } 
     public virtual string path { get; set; } 
     public virtual string thumbnail { get; set; } 
     public virtual int userid { get; set; } 
     public virtual int? placeid { get; set; } 
     public virtual int? eventid { get; set; } 
     public virtual DateTime? approved { get; set; } 
     public virtual DateTime date { get; set; } 
     public virtual bool finished { get; set; } 

     public virtual User User { get; set; } 
     public virtual Place Place { get; set; } 
     public virtual Event Event { get; set; } 

     public virtual ISet<PictureVote> Votes { get; set; } 
    } 

}

和它下面的映射:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Data" namespace="Data"> 
    <class name="Picture" table="pictures"> 
    <id name="picid"> 
     <generator class="sequence"> 
      <param name="sequence">pictures_picid_seq</param> 
     </generator> 
    </id> 
    <property name="path" /> 
    <property name="width" /> 
    <property name="height" /> 
    <property name="thumbnail" /> 
    <property name="userid" /> 
    <property name="placeid" not-null="false" /> 
    <property name="eventid" not-null="false" /> 
    <property name="approved" /> 
    <property name="date" /> 
    <property name="finished" /> 

    <many-to-one name="User" column="userid" class="Data.User,Data" insert="false" /> 
    <many-to-one name="Place" column="placeid" class="Data.Place,Data" insert="false" /> 
    <many-to-one name="Event" column="eventid" class="Data.Event,Data" insert="false" /> 
    <set name="Votes"> 
     <key column="picid" /> 
     <one-to-many class="PictureVote" /> 
    </set> 
    </class> 

</hibernate-mapping> 

我檢查表定義和所有類型似乎是根據定義的類(postgresql):

         Table "public.pictures" 
    Column |   Type    |      Modifiers       
-----------+-----------------------------+---------------------------------------------------------- 
picid  | integer      | not null default nextval('pictures_picid_seq'::regclass) 
path  | character varying(250)  | not null 
thumbnail | character varying(250)  | not null 
userid | integer      | not null 
placeid | integer      | 
date  | timestamp without time zone | not null 
finished | boolean      | not null default false 
width  | integer      | not null 
height | integer      | not null 
eventid | integer      | 
approved | timestamp without time zone | 

當裏面的代碼,以下工作得很好,在插入圖片表中的一行: ... ...

var plpic = new Picture 
       { 
        date = DateTime.Now, 
        width = img.Width, 
        height = img.Height, 
        path = pic_server_path, 
        thumbnail = thumb_server_path, 
        userid = CustomUserManagement.User.userid, 
        finished = false, 
        approved = null, 
        placeid = placeid 
       }; 
       session.Save(plpic); 
       session.Flush(); 

... ... 其每一次的作品確定(是的,我會盡快將它包裝在交易中)。

但是,後來,下面永遠不會奏效(這是一個MVC行動中的代碼): ... ...

Picture pic = session.Get<Picture>(picid); 
      // While debugging, I verified that the "pic" object above is retrieved just fine. 
      if (pic.userid != CustomUserManagement.User.userid || ModelState.IsValid == false) 
       return Json (new { status = "error" }); 

      using (ITransaction tx = session.BeginTransaction()) { 
       try 
      { 
       pic.finished = true; 

       tx.Commit(); 
      } 
      catch (Exception e) { 
       tx.Rollback(); 
       NHibernateHelper.DestroySession(); 

       return Json (new { status = "error" }); 
      } 
     } 

... ...... 但這始終拋出一個System.InvalidCastException:無法在NpgsqlTypes.NpgsqlTypesHelper + c_ Iterator11上從源類型轉換爲目標類型。 <>米 _C(System.Object的時間戳)[0x00000]在/Users/fxjr/Desenvolvimento/ProjetosOpenSource/Npgsql/NpgsqlSourceRelease/Npgsql2/src/NpgsqlTypes/NpgsqlTypesHelper.cs:608

我在做什麼錯?我在Mono 2.10.5中使用了.NET 4,即使Windows,NHibernate 3.2和Npgsql 2.0.11.91也是如此。我也使用postgresql 9.1.1,但我已將ansi_conforming_strings設置爲OFF以確保我的Nhibernate方言仍然有效。有關更多信息,更新其他類型的對象時會發生同樣的情況。

我已經發布了這個在nhusers列表中,並收到了一個非常好的建議,試圖嘗試不同的數據庫來檢查它是否是Npgsql的錯誤。然而,我現在沒有時間,因爲我開始認爲這是我的錯,而不是別人的,我以爲我會在這裏發佈這裏,然後在另一個數據庫中重新創建我的數據庫架構,並嘗試此代碼在裏面。我有點絕望,因爲時間對我來說就像是有點耗盡了。誰能救我這個嗎?

在此先感謝。

+0

我不確定,如果你仍然無能爲力,那麼你可以嘗試獲取交易中的圖片對象。在事務內部獲取對象,如果條件爲真,則更新對象並提交。 – Zohaib

+0

剛試過而且沒有成功,拋出了同樣的異常。任何其他想法? –

+0

你介意嘗試使用以前的Npgsql版本嗎?我認爲你應該在2.0.10中嘗試。我幾乎肯定這是Npgsql本身的一個錯誤。如果你能夠創建一個基於控制檯的再現這個錯誤,我很高興,所以我們可以解決這個問題。提前致謝。 –

回答

3

過了很久,我想我應該回到這裏來回答我自己的問題。
這不一定是NHibernate或Npgsql中的錯誤。
我在映射文件中犯了一個巨大的錯誤,通過兩次映射相同的列。這意味着在我的映射類中有一個int? eventid和一個Event Event都映射到同一列會產生問題,因爲NHibernate無法處理這個問題,即你必須選擇其中的一個。會發生什麼事是,NHibernate將生成具有比您的表中的實際列數更多的參數的查詢。在MS SQL服務器,它是比較容易理解的拋出的異常:

無效索引N爲此SqlParameterCollection以計數= N

另一種替代方法是,但設置插入=「假」和更新映射二者=「假」在其中之一,雖然這是沒有用的。
我想很多像我這樣的人(來自LINQ-TO-SQL)都會嘗試相同的技巧,並在以後遇到很多麻煩。可悲的是,我沒有在NHibernate的文檔中發現任何強調這一點的東西。

希望它可以幫助別人。

相關問題