howto: map a single column of comma-delimited values as a string[]

26 views
Skip to first unread message

Joe B

unread,
Jun 15, 2011, 10:33:18 AM6/15/11
to nhusers
is this possible?

for instance ...

Column1
---------------
a,b,c,d


i want to result in:

public virtual string[] Column1

Oskar Berggren

unread,
Jun 15, 2011, 1:41:31 PM6/15/11
to nhu...@googlegroups.com
Implement IUserType is at least one possibility.

/Oskar

2011/6/15 Joe B <joe.br...@gmail.com>:

> --
> You received this message because you are subscribed to the Google Groups "nhusers" group.
> To post to this group, send email to nhu...@googlegroups.com.
> To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
>
>

Giulio Petrucci

unread,
Jun 16, 2011, 10:50:44 AM6/16/11
to nhu...@googlegroups.com
Hi Joe,

On Wed, Jun 15, 2011 at 4:33 PM, Joe B <joe.br...@gmail.com> wrote:
> is this possible?
[cut]

I know that the answer I'm going to give is just hateful but... have
you considered using <element>?

<set name="..." table="...">
<key column="MyEntityId"/>
<element column="..." type="String"/>
</set>

HTH,
Giulio

--

Joe Brockhaus

unread,
Jun 28, 2011, 3:30:48 PM6/28/11
to nhu...@googlegroups.com
Hi Giulio - thanks for your reply. Sorry for just seeing your response.

I fear I'm not familiar enough with NH to know why your answer is hateful :-o, heh.

I'm actually using Fluent, so I'm going to post how I'd do such an element mapping over there. 

I have something like 20 lookup tables all defined this same way .. this specific table has one more column with the comma-delimited string that I need as an array.

 .. below is how it's mapped currently. (I have a plain text property mapped to the plain text of the column, and a read-only property that simply does a join to return an array)

I'm not sure what the implications of the element mapping above are, or if it was understood that this column is on the same table as the entity that's already being mapped. The element mapping seems pretty straightforward, but then I thought having to specify the table on the Set and a keycolumn would infer that when the TechSupportCloseCode entities are loaded, that 2 selects will be executed per entry?

public class TechSupportCloseCodeMap : ClassMap<TechSupportCloseCode>
   {
       public const string TS_CLOSE_CODE = "TS_CLOSE_CODE";

       public static class Fields
       {
           public const string CNR_BUSINESS_AREA_IDS = "CNR_BUSINESS_AREA_IDS";
       }

       public TechSupportCloseCodeMap()
       {
           base.Table(TS_CLOSE_CODE);

           this.DoLookupTypeMap();

           Map(x => x.CnrBusinessAreaIDsRaw, Fields.CNR_BUSINESS_AREA_IDS)
               .ReadOnly();
       }
   }

public static class ClassMapExtensions
   {
       public static void DoLookupTypeMap<T>(this ClassMap<T> map)
           where T : BaseLookupType
       {
           map.DoLookupTypeMap<T>(
               () => map.Id(x => x.ID, BaseLookupTypeMap.Fields.ID)
               );
       }
       public static void DoLookupTypeMap<T>(this ClassMap<T> map, Action IdMapAction)
           where T : BaseLookupType
       {
           map.Cache.ReadOnly();

           IdMapAction();

           map.Map(x => x.Code, BaseLookupTypeMap.Fields.CODE);
       }

   }


------
Joe Brockhaus
joe.br...@gmail.com
------------



--

jalchr

unread,
Jun 29, 2011, 5:21:06 AM6/29/11
to nhu...@googlegroups.com
I use '^' as a delimiter but same concept ... 

            Map(x => x.ExternalNotes).CustomType(typeof(StringArrayTypeMapper));



    public class StringArrayTypeMapper : PrimitiveType
    {
        public StringArrayTypeMapper()
            : base(new SqlType(DbType.String))
        {
        }

        public override object Get(IDataReader rs, int index)
        {
            var value = rs.GetString(index);
            return value.Split('c');
        }

        public override object Get(IDataReader rs, string name)
        {
            int ordinal = rs.GetOrdinal(name);
            return Get(rs, ordinal);
        }

        public override Type ReturnedClass
        {
            get { return typeof(string[]); }
        }

        public override object FromStringValue(string xml)
        {
            return xml.Split('^');
        }

        public override string Name
        {
            get { return "string[]"; }
        }

        public override void Set(IDbCommand cmd, object value, int index)
        {
            var parameter = (IDataParameter)cmd.Parameters[index];

            var val = (string[])value;

            parameter.Value = string.Join("^", val);
        }
        public virtual object NullSafeGet(IDataReader resultSet, string[] names, object owner)
        {
            int index = resultSet.GetOrdinal(names[0]);
            if (resultSet.IsDBNull(index))
            {
                return null;
            }
            string res = resultSet.GetValue(index) as string;
            if (res != null)
            {
                return res.Split('^');
            }
            throw new NotImplementedException();
        }
        public virtual void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            IDbDataParameter parameter = ((IDbDataParameter)cmd.Parameters[index]);
            if (value == null)
            {
                parameter.Value = DBNull.Value;
            }
            else
            {
                var list = (string[])value;
                parameter.Value = string.Join("^", list);
            }
        }
        public override string ObjectToSQLString(object value, Dialect dialect)
        {
            return value.ToString();
        }

        public override Type PrimitiveClass
        {
            get { return typeof(string[]); }
        }

        public override object DefaultValue
        {
            get { return null; }
        }
    }


fel0niousmonk

unread,
Jun 29, 2011, 9:45:14 AM6/29/11
to nhusers
nice! I wasn't aware it was that easy :)

Thanks much
Reply all
Reply to author
Forward
0 new messages