Re[3]: IMapGettable хочется
От: oleksab Украина  
Дата: 09.11.05 08:14
Оценка:
Здравствуйте, IT, Вы писали:

O>> Неудобно только то, что всем out параметрам нужно будет явно присваивать значение в реализации GetFieldstring fieldName, out object value).


IT>Да уж, как-то это всё не очень...


Не очень out? Его можно поменять на ref
Или сама идея вызывать IMapGettable.GetField в MapDescriptor.GetFieldValue плоха?
Можно переделать с ref как
        object IMapDataSource.GetFieldValue(string name, object entity)
        {
            IMemberMapper mm = this[name];

            object value = mm != null ? mm.GetValue(entity) : null;
            IMapGettable mg;
            if ((mg = entity as IMapGettable) != null && value != null)
            {
                mg.GetField(name, ref value);
            }
            return value;
        }

Тогда IMapGettable.GetField если захочет — изменит значение value. Ну а если нет — то нет.

IT>Я бы глянул в сторону конструктора с MapInitializeData параметром. Он перед маппингом получает в это структуре все необходимые данные.


Это в смысле Map.MapInternal? Но там проверку на реализацию IMapGettable прийдется делать в двух местах:

        Map.MapInternal(
                IMapDataSource   source,
                object           sourceData,
                IMapDataReceiver receiver,
                object           receiverData,
                MapInitializingData data)
        {
            if (receiverData is ISupportInitialize)
                ((ISupportInitialize)receiverData).BeginInit();
            // реализует ли sourceData IMapGettable
            IMapGettable mg = sourceData as IMapGettable;
            
            if (receiverData is IMapSettable)
            {
                IMapSettable mapReceiver = (IMapSettable)receiverData;

                for (int i = 0; i < source.FieldCount; i++)
                {
                    string name = source.GetFieldName(i);
                    object o    = source.GetFieldValue(i, sourceData);
                    // проверка №1 
                    if (mg != null)
                    {
                        // скажем для какого поля будет подставлено значение
                        mg.GetField(name, ref o);
                    }

                    MapDescriptor md = data.MapDescriptor;
                
                    if (mapReceiver.SetField(name, o) == false)
                    {
                        int idx = receiver.GetOrdinal(name);

                        if (idx >= 0)
                        {
                            receiver.SetFieldValue(idx, name, receiverData, o);
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < source.FieldCount; i++)
                {
                    string name = source.GetFieldName(i);

                    // -----------------------------------
                    if (name.Length > 0)
                    {
                        int idx  = receiver.GetOrdinal(name);

                        if (idx >= 0)
                        {
                            object o = source.GetFieldValue(i, sourceData);
                            // проверка №2
                            if (mg != null)
                            {
                                // скажем для какого поля будет подставлено значение
                                mg.GetField(name, ref o);
                            }
                            receiver.SetFieldValue(idx, name, receiverData, o);
                        }
                    }
                }
            }

            if (receiverData is ISupportInitialize)
                ((ISupportInitialize)receiverData).EndInit();
        }
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.