0

アプリケーションで Nhibernate を使用しています。私が新しいオブジェクトを保存したかったとき、時々、めったにではありません-常にではありません(これは私を驚かせ、狂わせます)-私は呼ばれるエラーに出くわしました:

NHibernate.TypeMismatchException:
間違ったタイプの ID が提供されました。期待される system.Decimal は system.String を取得しました

コンピュータとタブレット PC でプログラムを実行した場合、このエラーは発生しません。しかし、私のクライアントは一般的にこのエラーに遭遇する可能性があります...特に、オフィスの外でタブレット PC を使用して新しいレコードを保存したい場合。外部の言葉で言えば、タブレット PC では、モービル SIM カードでインターネット接続が提供されます。彼らは個人情報を得るために家に行きます。とにかく、一度に新しいレコードを挿入できる場合もありますが、2 番目のレコードでは、エラーが再び発生します... エラーの後、新しいレコードを再度挿入することはできません。そのため、アプリをログアウトし、再度ログインしようとすると、同じエラーが表示され、ログインできません。

データベースは MSSQL です。id は PK および 10 進数型です。自動インクリメントは true です。

私の側では問題を再現できなかったので、原因が何であるかを追跡するのは非常に困難です. 最大の問題は、常に発生するわけではないことです...原因を約2〜3日間グーグルで調べます...しかし、まだ解決策が思い浮かびません...奇妙なエラーです!

hbm ファイルは次のとおりです。

Hasta.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="DataLayer.DBStructure.Hasta,DBStructure" table="Hasta" lazy="true">
<id name="Id" column="id" type="Decimal">
  <generator class="native" />
</id>
<property name="Aktiflik" column="Aktiflik" type="Boolean" not-null="true" />
<many-to-one name="Hane" column="HaneId" cascade="none" />
<many-to-one name="Iletisim" column="IletisimId" cascade="none"/>
<many-to-one name="HastaIsco" column="HastaIscoId" cascade="none"/>
<many-to-one name="HastaNace" column="HastaNaceId" cascade="none"/>
<property column="KayitTarihi" type="DateTime" name="KayitTarihi" not-null="true" />
<property column="KullaniciId" type="string" name="KullaniciId" not-null="true" />
<bag name="HastaCokluParametreDeger" inverse="true" lazy="true" cascade="all">
  <key column="HastaId" />
  <one-to-many class="DataLayer.DBStructure.HastaCokluParametreDeger,DBStructure" />
</bag>

Hasta.cs

    public virtual decimal Id
    {
        get { return m_id; }
        set { m_id = value; }
    }
    public virtual Hane Hane
    {
        get { return m_hane; }
        set { m_hane = value; }
    }
    public virtual Boolean Aktiflik
    {
        get { return m_aktiflik; }
        set { m_aktiflik = value; }
    }
    public virtual Iletisim Iletisim
    {
        get { return m_iletisim; }
        set { m_iletisim = value; }
    }
    public virtual HastaIsco HastaIsco
    {
        get { return m_hastaisco; }
        set { m_hastaisco = value; }
    }
    public virtual HastaNace HastaNace
    {
        get { return m_hastanace; }
        set { m_hastanace = value; }
    }

    public virtual DateTime KayitTarihi
    {
        get { return m_kayittarihi; }
        set { m_kayittarihi = value; }
    }
    public virtual string KullaniciId
    {
        get { return m_kullaniciid; }
        set { m_kullaniciid = value; }
    }

    public virtual IList<HastaCokluParametreDeger> HastaCokluParametreDeger
    {
        get { return m_hastacokluparametredeger; }
        set { m_hastacokluparametredeger = value; }
    }

CodeBehind 側: 値が関連するコントロールに割り当てられた後、保存ボタンは次のようになります

     protected void Page_Init(object sender, EventArgs e)
    {
        _eski = base.GetBusinessLogic<ElektronikSaglikKaydiIslemleri>();
        Oturum ot = _eski.OturumBilgisiAl();
        oturumKullaniciId = ot.LoginEdenKisi.KisiId;
    }

     private void HastaBilgisiKaydetGuncelle()
    {
        try
        {
            _eski.HastaBilgisiKaydet(hasta, iletisim, cari);
            _eski.ClearHastaCache();
        }
        catch()
        { }
    }

    public void HastaBilgisiKaydet(Hasta Has, Iletisim iletisim, Cari cari)
    {
        try
        {
            this.Provider.Insert<Cari>(cari);
            iletisim.Cari = cari;
            this.Provider.Insert<Iletisim>(iletisim);
            Has.Iletisim = iletisim;
            this.Provider.Insert<Hasta>(Has);
            this.Provider.Commit();
        }
        catch (Exception)
        {
            this.Provider.Rollback();
        }
    }

    public void Insert<T>(T obj) where T : DBEntity
    {
        if (obj != null)
        {
            object newUniqueIdentifier = null;

            IClassMetadata tMeta = this.nhSess.SessionFactory.GetClassMetadata(typeof(T));
            if (!tMeta.HasIdentifierProperty) throw new Exception("'" + tMeta.EntityName + "' nesnesi için tekil tanımlayıcı(unique identifier) belirlenmemiş.");

            Type type = obj.GetType();
            PropertyInfo pi = type.GetProperty(tMeta.IdentifierPropertyName);

            //Özelliğin string olma durumuna göre tekil tanımlayıcı atama işlemi
            if (tMeta.IdentifierType.GetType() == typeof(NHibernate.Type.StringType))
            {
                newUniqueIdentifier = this.getIdentifiersNextValue<T>(obj);
                pi.SetValue(obj, newUniqueIdentifier, null);
            }
            if (trans == null)
            {
                trans = this.nhSess.BeginTransaction();
            }

            this.nhSess.Save(obj);
            InserLog(obj);
        }
    }

    private NHibernate.ISession nhSess
    {
        get
        {
            if (Disposing)
            {
                throw new ObjectDisposedException("Connection Provider");
            }
            if (_mySession != null)
            {
                if (!_mySession.IsOpen)
                    _mySession = null;
            }
            if (_mySession == null)
            {
                try
                {
                    MyInterceptor interceptor = new MyInterceptor();
                    interceptor.cp = this;
                    _mySession = getFactory().OpenSession(interceptor);
                    _mySession.CacheMode = CacheMode.Ignore;
                }
                catch (Exception ex)
                {
                    _mySession = null;
                    throw ex;
                }
            }
            return _mySession;
        }
    }

    public abstract class BusinessLogicBase
    {
    protected string SessionId { get; private set; }
    protected ConnectionProvider Provider
    {
        get
        {
            return ConnectionProvider.Current(SessionId);
        }
    }

    public BusinessLogicBase(string sessionId)
    {
        if (string.IsNullOrEmpty(sessionId))
        {
            throw new ArgumentNullException("SessionId");
        }
        this.SessionId = sessionId;
    }

Insert メソッドでは、文字列かどうかでデータ型をチェックする... 既存のプロジェクトの構造上にこのアプリケーションを構築したため、以前に追加されました。アドインのようなものです。この既存のプロジェクトはデータベースとして Oracle を使用し、ID のデータ型は文字列です。そのため、いくつかのカスタム機能を使用して値を 1 つずつインクリメントします。しかし、私のデータベースは SQL で、データ型は数値 (10 進数) です。自動インクリメントは真です。とにかく、Insert メソッドのそのコードを考慮すると、挿入プロセスには影響しないと思います。

4

1 に答える 1

0

とにかく、すでに助けたいと思っていた人たちに感謝します。

このリンクの助けを借りて問題を解決しました

セッションの読み込み方法を確認する必要がありましたが、関連するコードを編集する必要があることに気付きました。現在はすべて正常に機能しています...

おそらく、同じ問題に再び遭遇した場合は、リンクのこの質問と回答が適切な解決策の 1 つになる可能性があります...

それが役に立てば幸い...

于 2013-04-16T13:55:41.583 に答える