1

どうやら非常に奇妙な問題に直面しています (何か間違ったことをしているに違いありません。エラーが見つかりません!)。特定の POCO がデータベースに保存されると、何も起こりません。同じ POCO でいくつかのプロパティが変更されている場合、セッションのフラッシュ中に 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 |

コード内では、次のようにすると問題なく動作し、pictures テーブルに行が挿入されます: ... ...

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: Cannot cast from source type to destination type at NpgsqlTypes.NpgsqlTypesHelper+c_ Iterator11.<>m _C (System.Object タイムスタンプ) [0x00000] in /Users/fxjr/ をスローしますDesenvolvimento/ProjetosOpenSource/Npgsql/NpgsqlSourceRelease/Npgsql2/src/NpgsqlTypes/NpgsqlTypesHelper.cs:608

私は何を間違っていますか?Windows、NHibernate 3.2、および Npgsql 2.0.11.91 でも同じことが起こりますが、私は Mono 2.10.5 で .NET 4 を使用しています。私も postgresql 9.1.1 を使用していますが、Nhibernate の方言がまだ機能することを確認するために ansi_conforming_strings を OFF に設定しています。詳細については、他のタイプのオブジェクトを更新するときにも同じことが起こります。

私はすでにこれをnhusersリストに投稿しており、別のデータベースを試してNpgsqlのせいかどうかを確認することについて非常に良い提案を受けました。しかし、今はそのための時間がなく、他の誰かのせいではなく自分のせいだと思い始めているので、別のデータベースで db スキーマを再作成してこのコードを試す前に、これをここに投稿すると思いました初期化。時間がなくなってきたので、少し必死になっています.. 誰かこれで私を救ってくれませんか?

前もって感謝します。

4

1 に答える 1

3

久しぶりに、ここに戻って自分の質問に答えるべきだと思いました。
これは必ずしも NHibernate または Npgsql のバグではありません。
同じ列を2回マッピングすることで、マッピングファイルに大きな間違いを犯していました。これが意味することは、マップされたクラスに aint? eventidと aEvent Eventが両方とも同じ列にマップされると問題が発生するということです。NHibernate はこれに対処できないためです。つまり、いずれかを選択する必要があります。NHibernate は、テーブル内の実際の列数よりも多くのパラメーターを使用してクエリを生成します。MS SQL Server では、スローされた例外を理解しやすくなります。

Count=N のこの SqlParameterCollection の無効なインデックス N

もう 1 つの方法は、両方をマッピングすることですが、どちらか一方に insert="false" と update="false" を設定しますが、これはほとんど役に立ちません。
私のような (LINQ-TO-SQL から来た) 多くの人が同じ偉業を試み、後で​​多くの問題を抱えていると思います。残念ながら、NHibernate のドキュメントでこれを強調しているものは見つかりませんでした。

それが誰かを助けることを願っています。

于 2012-04-08T14:59:59.680 に答える