【问题标题】:Converting string to double in fluent-nhibernate mapping在流利的休眠映射中将字符串转换为双精度
【发布时间】:2011-07-07 16:40:46
【问题描述】:

我有一个 sql 表,其中包含一个字符串列,该列可以包含 null、空字符串或双精度值。 我想将此列映射到 double 的 C# 属性,当该列为空或为空时默认为零。 我可以使用流利的休眠映射来做到这一点吗? 我试过这个:

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

和这个主题的变体,但我总是收到转换失败的错误。

【问题讨论】:

    标签: fluent-nhibernate nhibernate-mapping


    【解决方案1】:

    现在我已经使用了一个自定义类型,它允许我使用

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

    这将满足我当前的需求。

    如果有人提出更简单的解决方案,我将暂时保留问题。

    DoubleString 类型的代码如下。

    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; }
        }
    }
    

    【讨论】:

    • 太好了,这解决了我必须将自定义 struct 作为字符串保存在数据库中的情况!如果您对如何修改上述内容有任何线索,我将不胜感激,但它适用于 Nullable&lt;?&gt; 类型。是否有必要将其更改为使用可空值,或者我只需要使用用户类型约定?
    • 这是一个非常好的答案。就我而言,我不得不将第 40 行的 ToString() 更改为:.ToString(System.Globalization.CultureInfo.GetCultureInfo("en-US"));,因为 ToString() 更改了双精度,例如1.23 到 1,23 并且 SQL 不接受它。对于文化,它保留点而不是逗号。
    【解决方案2】:

    我只是将它映射到一个字符串,并且在您的实体中具有一个可以进行转换的 double 属性。似乎比在映射中更容易和更干净。

    可能是这样的:

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

    【讨论】:

    • 我不太确定它是否更干净,我需要一个字符串属性供 NH 在保存时使用,并在从代码访问它时使用双属性。如果我理解你的建议是正确的。如果我只有一个 double 属性,那么 NH 会将其保存为 double 而不是字符串。
    • touché ...我的意思是把更清洁的部分拿出来。就您的映射而言,更清洁,但不是您的实体。在此解决方案中,您将拥有一个私有字符串变量和一个公共双属性
    【解决方案3】:

    我使用两个引用同一个私有变量的属性解决了同样的问题。在我的示例中,数据库包含一个未使用或实际的 varchar,因此我希望在我的应用程序中使用 bool。

        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"); }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多