2011-07-07 21 views
6

Boş, boş bir dize veya bir çift değer içerebilen bir dize sütun içeren bir sql tablom var. Sütunu boş veya boş olduğunda, bu sütunu double olan bir C# özelliğine eşlemek istiyorum. Bunu akıcı-nhibernate eşlemesiyle yapabilir miyim? Bu çalıştı: Bu tema üzerineDizeyi akıcı-nhibernate eşleştirmede ikiye dönüştürme

Map(p => p.doubleProperty).CustomSqlType("varchar(20)").CustomType("double").Default("0"); 

ve varyasyonlar ama her zaman dönüştürme başarısız olduğunu bir hata alıyorum.

cevap

1

Bunu bir dizeyle eşleştirebilirim ve varlığınızda, dönüşümü yapan bir çift özellik var. Haritalamada olduğundan daha kolay ve temiz görünüyor. Böyle

Belki bir şey:

public double Price 
{ 
    get 
    { 
     double price = -1.0; 
     Double.TryParse(stringProperty, out price); 
     return price; 
    } 
    set { stringProperty = value.ToString(); } 
} 
+0

, bir dize özelliğini gerekiyordu. Doğru bir şekilde önerdiğini anlıyorum. Eğer sadece bir çifte mülküm varsa, o zaman NH bir çiftten değil bir çifte olarak kaydeder. – Mike

+0

touché ... Temizleyici parçayı çıkarmak istedim. Haritalandırmanızla ilgili daha temiz, ancak sizin tarafınızdan değil. Bu çözümde, özel bir dize değişkeni ve bir kamu çift özelliği –

5

şimdi benim şimdiki ihtiyaçları için yapacak

 Map(p=>p.doubleProperty).CustomType<DoubleString>(); 

kullanmaya olanak sağlayan özel bir türü ile gidince için.

Birisi daha kolay bir çözüm bulması durumunda soruyu şimdilik açık bırakacağım.

DoubleString türü için kod aşağıdadır.

public class DoubleString : IUserType 
{ 
    public new bool Equals(object x, object y) 
    { 
     if (ReferenceEquals(x, y)) 
     { 
      return true; 
     } 
     if (x == null || y == null) 
     { 
      return false; 
     } 
     return x.Equals(y); 
    } 

    public int GetHashCode(object x) 
    { 
     return x.GetHashCode(); 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var valueToGet = NHibernateUtil.String.NullSafeGet(rs, names[0]) as string; 
     double returnValue = 0.0; 
     double.TryParse(valueToGet, out returnValue); 
     return returnValue; 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     object valueToSet = ((double)value).ToString(); 
     NHibernateUtil.String.NullSafeSet(cmd, valueToSet, index); 
    } 

    public object DeepCopy(object value) 
    { 
     return value; 
    } 

    public object Replace(object original, object target, object owner) 
    { 
     return original; 
    } 

    public object Assemble(object cached, object owner) 
    { 
     return DeepCopy(cached); 
    } 

    public object Disassemble(object value) 
    { 
     return DeepCopy(value); 
    } 

    public SqlType[] SqlTypes 
    { 
     get 
     { 
      return new[] { new SqlType(DbType.String) }; 
     } 
    } 

    public Type ReturnedType 
    { 
     get { return typeof(double); } 
    } 

    public bool IsMutable 
    { 
     get { return true; } 
    } 
} 
+0

Büyük olurdu, bu veritabanında bir dize olarak bir özel 'struct' devam etmek zorunda kaldı bir durum çözüldü! Yukardaki değişikliklerin nasıl yapılacağına dair herhangi bir ipucunuz varsa, Nullable 'türleriyle çalışsa da çok memnun olurum. Nemli ya da nart ile çalışmak için değiştirmek gerekiyor mu yoksa sadece kullanıcı tipi sözleşmesiyle oynamak için mi ihtiyacım var? –

+1

Onun çok güzel bir cevabı. Benim durumumda, 40. satırdaki 'ToString()' i değiştirmek zorunda kaldım: '.ToString (System.Globalization.CultureInfo.GetCultureInfo ("en-US")); 'ToString() işlevi çift değiştirir örneğin 1,23 'ile 1,23' arasında ve SQL bunu kabul etmedi. Kültür ile virgül yerine nokta tutar. – DontVoteMeDown

0

Aynı özel değişkeni ifade eden iki Özelliği kullanarak aynı sorunu çözdüm. Örneğimde veritabanı, KULLANILMAMIŞ veya GERÇEK OLMAYAN bir varchar içerir, bu yüzden başvurumda bir bool istedim. NH tasarrufu ve koddan erişirken çift özellik ne zaman kullanılacağını kullanmak için bunu daha temiz çok emin değilim

private bool _myBool= true; 

    public virtual bool MyBool{ get { return _myBool; } set { _myBool= value; } } 

    public virtual string MyString 
    { 
     get { return _myBool ? "ACTUAL" : "NOT USED"; } 
     set { _myBool= value.Equals("NOT USED"); } 
    } 
} 
İlgili konular