August 2009 - Einträge

Mysteriöse TimeoutException bei NHibernate

Ich hatte eine zeitlang einfach so eine TimeoutException, als ich mittelsn NHibernate und WCF Daten übertragen wollte. Der Fehler bestand aus zwei Problemen.

Erstens hatte ich Objekte vom Typ IList, die ich übertragen wollte. Das geht nicht, denn so ist ja gar nicht klar, was auf der anderen Seite erzeugt werden soll. Als ich dies nach List abänderte gings...

Parallel dazu gabs ein anderes Problem. Ich wollte, dass meine Entitäten von einer Basisentität erben, damit ich Gemeinsamkeiten nur einmal entwickeln muss. Und in der Schnittstelle sollte natürlich die Basisklasse angegeben werden, damit ich z.B. bei der Methode Add(DBEntityBase entity), auch jegliche Objekte angeben konnte, die von DBEntityBase erben. Dazu muss aber das Attribut KnownType benutzt werden, da er sonst nicht weiss, was denn nun eigentlich gemeint ist.

Diese beiden Fehler führten bei mir zu einer TimeoutException..

NHibernate unterschiedliche Typen mappen

NHibernate ist ein cooler OR-Mapper. Zusammen mit der Erweiterung Fluent NHibernate kann man damit schon ne ganze Menge machen. Ich hab ein kleines Projekt mit einer DB2-Datenbank. Dummerweise können die da bei IBM nich mal simple boolean. Warum auch. Ich würd lieber MSSQL nehmen, aber geht leider nicht.

Ich möchte in meinen Entitäten eine Boolsche Property haben, die unterm Hintern in der Datenbank auf int gemappt wird. Und hier die Lösung:

In der Entity schreibt man:

   1: public virtual bool IsActive { get; set; }

Im Mapper schreibt man:

   1: Map(x => x.IsActive).CustomType(typeof(BooleanType));

Und die Klasse BooleanType schreiben wir selbst. Damit das funktioniert muss sie das Interface IUserType implementieren. Hier ist der Code (ist aber erst die erste Version).

   1: public class BooleanType : IUserType
   2: {
   3:     #region IUserType Member
   4:     public bool IsMutable
   5:     {
   6:         get { return false; }
   7:     }
   8:     public Type ReturnedType
   9:     {
  10:         // Muss den Typ zurückgeben, den
  11:         // er repräsentiert, damit NHibernate-Linq-Methoden funktionieren
  12:         get { return typeof(bool); }        
  13:     }
  14:     SqlType baseType = new SqlType(System.Data.DbType.Int16);
  15:     public SqlType[] SqlTypes
  16:     {
  17:         get { return new[] { baseType }; }
  18:     }
  19:     public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
  20:     {
  21:         var obj = NHibernateUtil.Int16.NullSafeGet(rs, names[0]);
  22:         if (obj == null) return null;
  23:         bool bolVal = Convert.ToBoolean(obj);
  24:         return bolVal;
  25:     }
  26:     public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
  27:     {
  28:         if (value == null)
  29:         {
  30:             ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
  31:         }
  32:         else
  33:         {
  34:             bool bolVal = Convert.ToBoolean(value);
  35:              // Wenn true, dann eins (true), ansonsten 0 (false)
  36:             ((IDataParameter)cmd.Parameters[index]).Value = bolVal ? 1 : 0;
  37:         }
  38:     }
  39:     public object DeepCopy(object value)
  40:     {
  41:         if (value == null) return 0;
  42:         return value;
  43:     }
  44:     public object Replace(object original, object target, object owner)
  45:     {
  46:         return original;
  47:     }
  48:     public object Assemble(object cached, object owner)
  49:     {
  50:         return cached;
  51:     }
  52:     public object Disassemble(object value)
  53:     {
  54:         return value;
  55:     }
  56:     public new bool Equals(object x, object y)
  57:     {
  58:         if (ReferenceEquals(x, y)) return true;
  59:         if (x == null || y == null) return false;
  60:         return x.Equals(y);
  61:     }
  62:     public int GetHashCode(object x)
  63:     {
  64:         return x.GetHashCode();
  65:         //x == null ? typeof(bool).GetHashCode() + 473 : x.GetHashCode();
  66:     }
  67:  
  68:     #endregion
  69: }
Nico Franze Herzlich Willkommen auf meinem Blog. Ich bin Nico, freier Softwareentwickler sowie Autor für Fachzeitschriften. Hab mit .NET Version 1.0 begonnen (damals noch VB.Net) und bin dann schlussendlich bei C# gelandet. Mehr Infos gibts unter www.nfranze.de


Suche

Los

Translator Widget

Dieser Blog

Syndikation


Locations of visitors to this page