Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Petr Klekner
Člen
Avatar
Petr Klekner:26.1.2019 11:06

Zdravím mám takový problém, mám následující metodu, která kopíruje hodnotu vlastností z modelu do jiného. Je zde ještě jedna věc na víc a to že je to buď podle jména a nebo podle atributu. To funguje jak má, jde mi teď o to, že pokud bude vlastnost můj objekt, tak bych chtěl aby se ta metoda provolal znova s tímhle objektem. JE to možné´? Popřípadě jak prosím. Metoda

public static void CopyPropertyValuesTo(this object model1, object model2)
{
    ICollection<PropertyInfo> properties1 = model1.GetType().GetProperties();
    ICollection<PropertyInfo> properties2 = model2.GetType().GetProperties();

    foreach (var property in properties1)
    {
        var attr = (property.GetCustomAttributes(typeof(PropertyName), true).SingleOrDefault() as PropertyName) ?? new PropertyName();
        attr.AllowNames.Add(property.Name);
        foreach (var allowName in attr.AllowNames)
        {
            var property2 = properties2.FirstOrDefault(x => x.Name == allowName);
            if (property2 != null)
            {
                model2.GetType().GetProperty(allowName).SetValue(model2, property.GetValue(model1));
            }
        }
    }
}

Příklad

class Trida1 {
        public int A {get; set;}
        public int B {get; set;}
        public JinyObjekt O {get; set;}
}

class Trida2 {
        public int A {get; set;}
    public int B {get; set;}
    public JinyObjekt O {get; set;} - Nevím jak
}

Předem moc děkuji

Zkusil jsem: Hledat na internetu, ale nevím jak přesně problém interpretovat

Chci docílit: Dobré funkčnosti a ulehčení práce

 
Odpovědět
26.1.2019 11:06
Avatar
Martin Petrovaj
Tvůrce
Avatar
Odpovídá na Petr Klekner
Martin Petrovaj:26.1.2019 12:34

Ak som dobre rozumel tvojej otázke, tak chceš, aby sa rovnakým spôsobom spravila deep copy aj vlastností ďalších objektov, ktoré sú v tých vlastnostiach? (napr. zavolám CopyPropertyVa­luesTo na objekte typu Trida1 a začne to kopírovať aj vlastnosti objektu O)

V tom prípade by ti malo stačiť vložiť podmienku v štýle if (!property.Pro­pertyType.IsVa­lueType) a v prípade jej splnenia zavolať rekurzívne tú tvoju metódu, nie?

Nehovorím, že je to dobré riešenie a odporúčal by som ti pozrieť sa na toto vlákno, ale malo by to robiť to, čo chceš.

Nahoru Odpovědět
26.1.2019 12:34
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Petr Klekner
Člen
Avatar
Odpovídá na Martin Petrovaj
Petr Klekner:26.1.2019 16:28

To je deep copy, ale tohle je trošku něco jiného ne? Ono já jsem to ještě trošku blbě nastínil... Může to být třeba typ JinyObjekt1 a JinyObjekt2, ale mají stené property! Nebo prostě chci aby se překopírovali stejné property. :) A ano máš pravdu, ale já nevím jaké tam dát parametry při tom dalším volání... to je vše co potřebuju

 
Nahoru Odpovědět
26.1.2019 16:28
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Petr Klekner
vajkuba1234:26.1.2019 19:18

Zkousel jsi AutoMapper?

Nahoru Odpovědět
26.1.2019 19:18
No hope, no future, JUST WAR!
Avatar
Petr Klekner
Člen
Avatar
Odpovídá na vajkuba1234
Petr Klekner:27.1.2019 0:05

AutoMapper používám, ale tady je to trochu problém. Nemám stejný objekt A a B. Mam různé modely a chci prostě překopírovat pouze jejich hodnoty podle jména, popřípade atributu. A nějak jsem nenašel, jak tohle udělat u autommaperu, já ho používám, když mám model z ef a dávám si ho do svého. A nenašel jsem, jak to udělat v kódu za běhu, protože to musím všechno nakonfigurovat před spuštěním...

 
Nahoru Odpovědět
27.1.2019 0:05
Avatar
Petr Klekner
Člen
Avatar
Petr Klekner:28.1.2019 7:41

Věděl by někdo?

 
Nahoru Odpovědět
28.1.2019 7:41
Avatar

Člen
Avatar
Odpovídá na Petr Klekner
:28.1.2019 14:12

Chceš klonovat property dvou zcela různých objektů pouze na základě shodného názvu a i případně typu vlastnosti?
Něco jako, projdu objektem 1 a hledám co property v objektu 2, a když je jméno a případně typ je shodný tak provedu kopii (hodnot hodnotových typů, tak i nových instancí typů podobjektů).
A pokud se tedy kopíruje podobjekt jako vlastnost, tak se opět hledá od začátku a kopírují se z podobjektu poze shodné názvy/typy?
Pak by stačila obyčejná rekurze... mechanismus tvorby podobjektů by mohl byl shodný s kořenovým způsobem vytvoření "kopie" objektu...uff.
Problém je snad jen v tom, že nikdy nevíš co vlastně vracíš a kopíruješ pouze něco, co se stejně jmenuje a nejde ti o objektovou strukturu, ale pouze o datový rámec kopírovaného složeného objektu.
Tím pádem mi přijde, že se porušují naprosto všechny pravidla objektového programování. Můj skromný názor.

 
Nahoru Odpovědět
28.1.2019 14:12
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na
vajkuba1234:28.1.2019 15:16

Ktera pravidla OOP by byla porusena? Mohl bys to vice rozvezt?

Nahoru Odpovědět
28.1.2019 15:16
No hope, no future, JUST WAR!
Avatar
Petr Klekner
Člen
Avatar
Odpovídá na
Petr Klekner:28.1.2019 18:51

Chápu jak to myslíš, ale tohle je věc kterou budu používat opravdu jen ve vyjmečných situací. Jde o to, že například jeden objekt bude mít více vlastností a druhý jenom 2, zde nejspíše nemůžu použít autommaper, protože objekty nejsou totožné, tohle je jenom moje doměnka, kdyžtak mě prosím opravte. No tak to muzu udělat způsobem

new Model() { ID = model.ID, Name = model.Name}

Když koukneš na net, tak je toho spousta a jde opravdu jen o usnadněnía používat to budu zřítka, takze sem to chtěl použíz. A napadlo mě, že by bylo fajn i kdyby to umělo rekurzivně, samozřejme to funguje i bez toho, takze si nad tím podojbektem zavolám stejnou metodu

 
Nahoru Odpovědět
28.1.2019 18:51
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Petr Klekner
vajkuba1234:28.1.2019 20:45

No bud si to budes mapovat sam a nebo treba posli priklady trid, ktere jsou rozdilne a chces je mapovat. Treba to jde, akorat narazis na neznalost automapperu. :)

Editováno 28.1.2019 20:46
Nahoru Odpovědět
28.1.2019 20:45
No hope, no future, JUST WAR!
Avatar

Člen
Avatar
Odpovídá na vajkuba1234
:29.1.2019 8:20

Ok...Nejde o pravidla - každý si je porušuje podle svého a podle potřeby - jde o filosofii. Tak třeba už jen z podstaty věci, že se pracuje s něčím, co má být uceleným popisem "logické" struktury, a má se s ní podle nějakých pravidel pracovat a přelévat se do jiných "logických" struktur, se najednou dá pracovat "bez logiky", jen na základě něčeho tak vágního, jako že se něco stejně jmenuje...
Jinak, než bez kontroly typu (a nebo jiných vlastností properties), si nedovedu představit, že by to kdy fungovalo jinak, než jen jako potenciální generátor chyb.
Vidím už problém jenom v tom, že u některých vystavených read-only properties, které nastavuje nějaká objektová logika tu hodnotu nezkopírujete nikdy "dokonale" (záleží co to vnitřně řeší)... zjeména pokud jde o dva různé objekty mající jen stejně pojmenovanou vlastnost, které mohou být svým implementovaným významem v každém z objektů na hony si vzdálené. Jen názor.

 
Nahoru Odpovědět
29.1.2019 8:20
Avatar
Samuel Kodytek
Tvůrce
Avatar
Samuel Kodytek:29.1.2019 8:38

Příjde mi to jako velmi špatný návyk... pokud něco takového řešíš tak bych řekl, že máš špatně navrženou architekturu aplikace...

Nicméně asi by to šlo přes reflexi. Momentálně nejsem doma, ale odpoledne až budu mít čas se ti můžu pokusit napsat nějakou extension funkci, která by zkopírovala vlastnosti z jednoho objektu do druhého.

Určitě se ale zamysli ještě jednou nad OOP návrhem tvé aplikace. Tyhle věci jsou většinou znak špatného návrhu.

Nahoru Odpovědět
29.1.2019 8:38
There is more than one way to screw it
Avatar
Petr Klekner
Člen
Avatar
Odpovídá na Samuel Kodytek
Petr Klekner:29.1.2019 16:45

vajkuba1234:
Dobře příklad třídy

Model1:

public int ID { get; set; }
      public string Name { get; set; }
      public string Descrtiption { get; set; }
      public string ID_AdvertisementState { get; set; }
      public int ID_Category { get; set; }
      public string ID_AdvertisementType { get; set; }
      public System.DateTime DateCreate { get; set; }
      public string DealerPhone { get; set; }
      public string DealerName { get; set; }
      public string DealerEmail { get; set; }
      public Nullable<decimal> Price { get; set; }
      public string DealerFacebook { get; set; }
      public bool IsDealerEmailShow { get; set; }
      public bool IsDealerPhoneShow { get; set; }
      public bool IsPriceDeal { get; set; }
      public bool IsActive { get; set; }
      public string Password { get; set; }
      public int ID_Village { get; set; }
      public System.Guid VerifyKey { get; set; }
      public bool IsVerify { get; set; }
      public int ID_Dealer { get; set; }

      public virtual AdvertisementState AdvertisementState { get; set; }
      public virtual AdvertisementType AdvertisementType { get; set; }
      public virtual Category Category { get; set; }
      public virtual ICollection<ImageAdvertisement> Images { get; set; }
      public virtual Village Village { get; set; }

Model2:

public string Name { get; set; }
public string ID_AdvertisementState { get; set; }
public int ID_Category { get; set; }
public string ID_AdvertisementType { get; set; }
public IEnumerable<int> Images { get; set; }
public Int32? ID { get; set; }

Možná to tim automapperem de, ale možná kvůli mé neznalosti to nejde...

martin.svoboda,Sa­muel Kodytek
Já zcela dobře nechápu co je na tom špatného :( Jde mi jenom o to, že nechci psát

Model m1 = new Model() {
        x.ID = m2.ID,
        x.Name = m2.Name
}

Ale jenom m1.CopyProper­tyValues(m2);
Vím jaké tam mám vlastnosti, neměl by to být problém... A de mi taky o to, že nevím, proč bych měl mít špatný návrh... Když tak se omlouvám, jenom mi to není jasné a je to i dost diskutované, je to jenom takový ulehčení, které sebou nenese moc problémů a navíc tam mam atribut pokud se jména liší
https://stackoverflow.com/…with-c-sharp
https://www.pluralsight.com/…g-reflection

Autommaper funguje na podobný způsob

 
Nahoru Odpovědět
29.1.2019 16:45
Avatar
Martin Petrovaj
Tvůrce
Avatar
Odpovídá na Petr Klekner
Martin Petrovaj:29.1.2019 16:58

Automapper sa dá nakonfigurovať tak, aby ti pri mapovaní z jedného typu na druhý určité vlastnosti ignoroval (https://stackoverflow.com/…tial-mapping).

Možno by som ti ešte navrhol alternatívne riešenie - ValueInjecter, najmä jeho metódu InjectFrom.
https://github.com/…alueInjecter
https://stackoverflow.com/…alueinjecter

Pokiaľ by si sa rozhodol použiť ten Automapper, tak čo sa týka mapovania vnorených objektov, toto mi možno trochu pomôže: https://stackoverflow.com/…ts-using-aut

I mean, je super, ak si tú funkcionalitu vieš napísať pomocou reflexie sám, ale pokiaľ to náhodou potrebuješ v práci, tak tam nemáš veľmi priestor na to vymýšľať znovu koleso. Ak je k dispozícii hotové riešenie, ktoré poskytuje viac funkcionality, je poriadne otestované, odladené a udržiavané niekým iným, tak nemá veľmi zmysel snažiť sa spraviť to isté na kolene. A takmer vždy je rýchlejšie stráviť pol hodinu nad dokumentáciou a Stack Overflow, aby som si doplnil medzery v znalostiach, než stráviť hodiny písaním vlastného ad hoc kódu od brucha.

Nahoru Odpovědět
29.1.2019 16:58
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na
vajkuba1234:29.1.2019 22:24

Slysel jsi nekdy treba o Data Transfer Object? :-)

Nahoru Odpovědět
29.1.2019 22:24
No hope, no future, JUST WAR!
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Petr Klekner
vajkuba1234:29.1.2019 22:29

Co ja vim, tak pri mapovani z jednoho modelu na druhy, i pri rozdilnem poctu properties, Automapper namapuje property se stejnym jmenem. Proste to umi.

Jak je to s vnorenymi objekty nevim, ale mapping z Modelu na Viewmodel a naopak je uplne normalni vec - navic viewmodel nutne nemusi korespondovat s modelem 1:1...

Ty modely co jsi poslal jsou tve vlastni vytvory?

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
29.1.2019 22:29
No hope, no future, JUST WAR!
Avatar
Odpovídá na vajkuba1234
Vlastimil Juračka:29.1.2019 23:21

Jsem to ale blbec.... V tom autommaperu jsem měl jiný problém a myslel jsem, že mi to nefunguje kvůli tomuhle... Nicméně díky autommaper to normálně umí :) Takže se moc omlouvám, ale i tak moc děkuji za rady. A ještě jeden rychlý dotaz, existuje u autommaperu například nějaký atribut, aby to neporovnával pouze podle názvu? Například mám v jednom modelu Cislo1 a v druhém Cislo2 a chtěl bych aby mi to autommaper spojil. Jde to nějak v configu autmmaperu nebo přes ten atribut? Díky

 
Nahoru Odpovědět
29.1.2019 23:21
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Vlastimil Juračka
vajkuba1234:29.1.2019 23:44
https://automapper.readthedocs.io/en/latest/Custom-value-resolvers.html
Nahoru Odpovědět
29.1.2019 23:44
No hope, no future, JUST WAR!
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Vlastimil Juračka
vajkuba1234:30.1.2019 1:22

Tady je spravny link

https://automapper.readthedocs.io/en/latest/Projection.html
Nahoru Odpovědět
30.1.2019 1:22
No hope, no future, JUST WAR!
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Petr Klekner
vajkuba1234:30.1.2019 1:25

Tady je vnorene mapovani

https://automapper.readthedocs.io/en/latest/Nested-mappings.html

Hlavne, ono by stacilo kouknout na google, dokumentaci a nebo treba na Github :)

Nahoru Odpovědět
30.1.2019 1:25
No hope, no future, JUST WAR!
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Petr Klekner
vajkuba1234:31.1.2019 10:48

Pomohlo?

Nahoru Odpovědět
31.1.2019 10:48
No hope, no future, JUST WAR!
Avatar
Petr Klekner
Člen
Avatar
Odpovídá na vajkuba1234
Petr Klekner:31.1.2019 11:13

Omlouvám se, byl jsem teď mimo PC. Určitě! Strašně moc děkuju. :) Jsem blbec... A na to mapování ano vím, že můžu požít googlu, ale rovnou jsem se zeptal, když tu byl člověk co tomu rozumí. Ještě jednou díky moc

 
Nahoru Odpovědět
31.1.2019 11:13
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 22 zpráv z 22.