class A
{
public int Id{get;set;}
}
class B
{
public int Id{get;set;}
public A A{get;set;}
}
class BMap
{
public int Id{get;set;}
public int AId{get;set;}
}
Как можно замапить B на BMap и обратно ? Вешать атрибуты на B и A нельзя.
Dog>>Как можно замапить B на BMap и обратно ? Вешать атрибуты на B и A нельзя. ili>TypeExtension тебя должен спасти, позволяет настраивать маппинг через xml пример здесь
а можно как-то в виде ?
class BMap
{
public int Id{get;set;}
[MapField("A.Id")]
public int AId{get;set;}
}
Здравствуйте, Dog, Вы писали:
Dog>а можно как-то в виде ?
можно, от чего же нельзя...
давай рассмотрим все на примере того же теста итак, имеем:
// вот у нас класс, с мапингом, размеченым аттрибутами, обратим внимание на то, что имена полей не совпадают с теми что в БДpublic class Person
{
[PrimaryKey]
[MapField("PersonID")] public int ID;
[MapField("FirstName")] public string FName;
[MapField("LastName")] public string LName;
}
[Test]
public void Test()
{
// вот тут мы делаем выборку из БД
Person p = (Person)new SqlQuery().SelectByKey(typeof(Person), 1);
// вот тут проверяем, что отмапилось все верно
Assert.AreEqual(1, p.ID);
Assert.AreEqual("John", p.FName);
Assert.AreEqual("Pupkin", p.LName);
// теперь начинается самое интересное
// 1. создается маппинг схема, новая, зачем, все просто - экстеншены грузятся в схему, где и хранятся
// пользуя для экстеншенов свою схему, мы как-бы не влиеям на дефолтную
MappingSchema map = new MappingSchema();
// 2. вот тут грузятся экстеншены из XML файла
// что интересно - файл может как лежать "рядом" с приложением, так и быть ембеднутым ресурсом
// сам файл приведен чуть ниже
map.Extensions = TypeExtension.GetExtensions("XmlMap.xml");
// вот тут мы мапим объект к ДатаРоу
DataRow dr = map.MapObjectToDataRow(p, new DataTable());
// а вот тут проверяем, что разметка полей _изменилась_ на ту, которую задает экстеншн
Assert.AreEqual(1, dr["PERSON_ID"]);
Assert.AreEqual("John", dr["FIRST_NAME"]);
Assert.AreEqual("Pupkin", dr["LAST_NAME"]);
}
а вот собственно наша XML-ка... тут все прозачно до безобразия, комментировать не буду...
такой экстеншн эквивалентен вот такой разметке аттрибутами:
public class Person
{
[MapField("PERSON_ID")] public int ID;
[MapField("FIRST_NAME")] public string FName;
[MapField("LAST_NAME")] public string LName;
}
все что можно задать в XML-ке задано 2 схемами: Mapping.xsd — позволяет задать то, что относится к маппингу, имена полей, типы, значения по умолчанию и прочая шняга, в принцыпе оно там прямо так словами и перечислено, аттрибуты совпадают с аттрибутами полей (простите за тафтологию), разобраться достаточно просто DataAccess.xsd — тут про датааксесс, тэйбл неймы, примари кеи, нон апдейтаблы
посмотрите в тестах *.xml, думаю, после этой короткой вводной разобраться не составит труда, если что — вэлкам, спрашивйте
ili>посмотрите в тестах *.xml, думаю, после этой короткой вводной разобраться не составит труда, если что — вэлкам, спрашивйте
У меня MapObjectToObject. С xml я понял, поковыряюсь на досуге. Меня интересует как расширить существующую функциональность, что бы можно было помечать атрибутами. (для самых простых случаев, без всяких там циклических ссылок и т.д...)
Здравствуйте, Dog, Вы писали:
Dog>У меня MapObjectToObject. С xml я понял, поковыряюсь на досуге. Меня интересует как расширить существующую функциональность, что бы можно было помечать атрибутами. (для самых простых случаев, без всяких там циклических ссылок и т.д...)
все едино... в смысле весь мапинг — единообразен, и разницы м\д ОбдектТуОбджект, или ОбджектТуДатаРоу — по сути нет.
Dog>>У меня MapObjectToObject. С xml я понял, поковыряюсь на досуге. Меня интересует как расширить существующую функциональность, что бы можно было помечать атрибутами. (для самых простых случаев, без всяких там циклических ссылок и т.д...) ili>все едино... в смысле весь мапинг — единообразен, и разницы м\д ОбдектТуОбджект, или ОбджектТуДатаРоу — по сути нет. ili>в какую сторону расширить-то? чего не хватат? =)
Не хватает маппинга на поля вложенных объектов не юзая xml. Смотри первый пост
Dog>>Не хватает маппинга на поля вложенных объектов не юзая xml. Смотри первый пост ili>эмн... там про атрибуты было, а про xml ничего ili>вообще если еще и без XML (читать метаданные) то, в общем случае, нужен телепатический модуль...
Нет, общий случай не надо А в чём там могут быть проблемы ?
ili>а вообще можно попробовать сварганить свой мапер раздел Map & MappingSchema подраздел Семейства Map
Угу, видимо это и надо...
Здравствуйте, Dog, Вы писали:
ili>>вообще если еще и без XML (читать метаданные) то, в общем случае, нужен телепатический модуль... Dog>Нет, общий случай не надо А в чём там могут быть проблемы ?
нуу... ходят слухи, что постоянные занятия телепатией приводят к образованию раковых опухолей мозга у людей, и выгоранию процессоров и памяти у компов
а если серъезно, то проблема одна — как без метадаты понять чо делать?
вот в твоем примере, через какое место можно сообразить, что B.A.Id <=> BMap.AId?
метадата — задает правила, а если нет правил, то, в общем случае, все неправильно (по определению )
ili>а если серъезно, то проблема одна — как без метадаты понять чо делать? ili>вот в твоем примере, через какое место можно сообразить, что B.A.Id <=> BMap.AId?
Как-то так...
class A
{
public int Id{get;set;}
}
class B
{
public int Id{get;set;}
public A Aa{get;set;}
}
class BMap
{
public int Id{get;set;}
[MapField("Aa.Id")]
public int AId{get;set;}
}
ili>вот в твоем примере, через какое место можно сообразить, что B.A.Id <=> BMap.AId?
Разобрался с Xml всё работает (не скажу что было тривиально ) Получилось что-то в виде:
Смотрю в сорцы и меня мучает вопрос. Как кошернее расширить функциональность ?
Набросал быстро вот это, но не совсем нравиццо.
public class ObjectMapperEx : ObjectMapper
{
public void UpdateMapper(IEnumerable<string> names)
{
foreach (var name in names)
{
var mm = GetComplexMapper(name, name);
if (mm != null)
{
Add(mm);
}
}
}
public IEnumerable<string> GetMapFields()
{
var names = new List<string>();
foreach (MemberAccessor ma in TypeAccessor)
{
if (GetMapIgnore(ma))
{
continue;
}
var mapFieldAttr = ma.GetAttribute<MapFieldAttribute>();
if (mapFieldAttr != null)
{
names.Add(mapFieldAttr.MapName);
}
}
return names;
}
}
public class MappingSchemaEx : MappingSchema
{
protected override ObjectMapper CreateObjectMapperInstance(Type type)
{
return new ObjectMapperEx();
}
public object MapObjectToObject(object sourceObject,object destObject)
{
var dest = (ObjectMapperEx)GetObjectMapper(destObject.GetType());
var source = (ObjectMapperEx)GetObjectMapper(sourceObject.GetType());
source.UpdateMapper(dest.GetMapFields());
MapInternal(null,source, sourceObject,dest, destObject);
return destObject;
}
}
ну тык почти
мапинг работает по алиасам, т.е. то у чего одинаковые алиасы считается "про одно и тоже"
по умолчанию в поля, которые мапятся попадают, грубо говоря, скалярные типы.
так что если сделать так, то все должно арбайтен:
class A
{
public int Id{get;set;}
}
[MapField("AId", "Aa.Id")]class B
{
public int Id{get;set;}
public A Aa{get;set;}
}
class BMap
{
public int Id{get;set;}
public int AId{get;set;}
}
ili>ну тык почти ili>мапинг работает по алиасам, т.е. то у чего одинаковые алиасы считается "про одно и тоже" ili>по умолчанию в поля, которые мапятся попадают, грубо говоря, скалярные типы.
Это я уже понял. Теперь вопрос стоит, как, с точки зрения архитектуры, привильнее подключить ComplexMapper ?
Я написал решение
, но оно мне не совсем нравится. Может лучше было бы сделать свой MetadataProvider или ещё как...
ili>так что если сделать так, то все должно арбайтен:
[MapField("AId", "Aa.Id")]class B
{
public int Id{get;set;}
public A Aa{get;set;}
}
Здравствуйте, Dog, Вы писали:
Dog>Разобрался с Xml всё работает (не скажу что было тривиально ) Получилось что-то в виде:
ничо не понимаю... все и так работает, и ничего допиливать не надо...
public class A
{
public int Id { get; set; }
}
public class B
{
public B()
{
Aa = new A();
}
public int Id { get; set; }
public A Aa { get; set; }
}
public class BMap
{
public int Id { get; set; }
public int AId { get; set; }
}
[Test]
public void Test1()
{
B b = new B();
b.Id = 1;
b.Aa.Id = 2;
MappingSchema m = new MappingSchema();
m.Extensions = TypeExtension.GetExtensions("Extension.xml");
BMap bm = m.MapObjectToObject<BMap>(b);
Assert.AreEqual(b.Id, bm.Id);
Assert.AreEqual(b.Aa.Id, bm.AId);
B newB = m.MapObjectToObject<B>(bm);
Assert.AreEqual(b.Id, newB.Id);
Assert.AreEqual(b.Aa.Id, newB.Aa.Id);
}
Dog>>Разобрался с Xml всё работает (не скажу что было тривиально ) Получилось что-то в виде: ili>ничо не понимаю... все и так работает, и ничего допиливать не надо...
Я писал, что разобрался с xml. Теперь мне интересно как правильно сделать без xml.
Что-нибудь ещё не понятно ?
Здравствуйте, Dog, Вы писали:
Dog>Я писал, что разобрался с xml. Теперь мне интересно как правильно сделать без xml. Dog>Что-нибудь ещё не понятно ?
дыы... ты меня окончательно запутал мне терь ваще ничо непонятно =))
писать свой обджект маппер
ну то что ты там пару постов выше нарисовал, то поркуа бы не па, тока ниясно зачем всегда вызывать UpdateMapper? есть метод Init в нем заполняются мембер маперы, его можно успешно допилить.
ток вызывается он вроде всего один раз при создании обджект мапера, если у тебя правила не меняются, то лучше мембер маперы дозаполнять в нем.
ili>дыы... ты меня окончательно запутал мне терь ваще ничо непонятно =))
Ну вот опять
Есть задача сделать мапинг объект на объект не используя xml. Понятно ?
Вот такие классы. (мапинг B <-> BMap). Понятно ?
class A
{
public int Id{get;set;}
}
class B
{
public int Id{get;set;}
public A Aa{get;set;}
}
class BMap
{
public int Id{get;set;}
public int AId{get;set;}
}
На А и В атрибуты вешать нельзя. Понятно ?
Метадату я описал так
class BMap
{
public int Id{get;set;}
[MapField("Aa.Id")]public int AId{get;set;}
}
В этом случае BMap -> B мапится, а наоборот — нет.
Вот вроде и всё...
ili>писать свой обджект маппер ili>ну то что ты там пару постов выше нарисовал, то поркуа бы не па, тока ниясно зачем всегда вызывать UpdateMapper? ili>есть метод Init в нем заполняются мембер маперы, его можно успешно допилить.
Можно. Я как раз хотел заюзать GetComplexMapper(string mapName, string origName) , чтобы не изобретать свой
Но не понял как мне получить в Init mapName и origName (в нашем случае они будут равны). Поэтому я пробежался по destObject получил mapName у MapField и обновил мембер маперы у sourceObject.
Ессно, мне это не нравиццо. Вот я и спрашиваю, как можно лучше?
ili>ток вызывается он вроде всего один раз при создании обджект мапера, если у тебя правила не меняются, то лучше мембер маперы дозаполнять в нем.
Это ясно.
ili>вот те еще вариант, если нельзя получать TypeExtension из XML, то почему бы его не формировать на основе BMap?
Мы конечно не ищем лёгких путей, но это уже слишком