Я использую Nhibernate в своем приложении. , когда я хотел, чтобы сохранить новый объект, иногда, но редко-не все время (это делает меня сюрпризом и ума) - я наткнулся на ошибку, которая называется:NHibernate.TypeMismatchException: предоставлен идентификатор неправильного типа. ожидаемая система.Decimal получил system.string
NHibernate.TypeMismatchException:
при условии, идентификатор неправильный тип. ожидаемая система.Decimal получила system.String
Эта ошибка не возникает, когда я запускал программу на своем компьютере и на планшетном ПК. , но мои клиенты могут встретить эту ошибку вообще ... Особенно, когда они хотели сохранить новую запись, используя планшетные ПК вне офиса. с наружным словом, я имею в виду в планшетных ПК, подключение к Интернету обеспечивается мобильными сим-картами. Они идут в дома, чтобы получить информацию о человеке. В любом случае, иногда они могут вставлять новую запись сразу, но для второй записи ошибка возникает снова ... после ошибки невозможно вставить новую запись снова. Поэтому они выходят из приложения и когда они хотят снова войти в систему, отображается одна и та же ошибка, и войти в систему невозможно.
База данных MSSQL. id - это PK и десятичный тип. auto-increment - true.
Я не мог воспроизвести проблему на моей стороне, поэтому очень сложно проследить, в чем причина. Самая большая проблема заключается в том, что это не происходит все время ... googling причина примерно на 2-3 дня ... но еще не придумали какое-либо решение ... странная ошибка!
НВМ файлы:
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;
}
В методе Вставки он проверяет тип данных в зависимости от того, является ли он строкой или нет ... Он добавлен ранее, потому что я создал это приложение в структуре существующего проекта. это как надстройка. Этот существующий проект использует Oracle, поскольку тип данных базы данных и идентификаторов - это строка. поэтому они увеличивают свои значения один за другим, используя некоторые пользовательские функции. но моя база данных - это SQL, а тип данных - числовое (десятичное). auto increment - true. Во всяком случае, этот код в методе Insert, учитывая, я не думаю, что это влияет на процесс вставки.
С подозрением, что это не помогает при перезагрузке приложения. Как вы управляете своими сеансами? –
@OskarBerggren Я снова редактировал блок кода. Во время процесса вставки, как я вызываю метод insert, то, что включает метод insert и как вызов nhibernate вызывается для сохранения, добавляется, чтобы получить компромисс очень хорошо. –
Вы используете какое-то распределенное кэширование, локальное хранилище с сериализацией? – jbl