• 13 odgovora
  • 3.827 pregleda
LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 09:31 · pre 194 meseci #1
Prica pocinje ovako ...
Code:

var queryOne = .....select new ... // neke vrednosti

Sada tu imam datume neke 1,2,5,7, gde fale 3,4,6...
Ja napravim jedan niz sa svim datumima od najmanjeg do najveceg koji se nalaze u queriju i napravion sa novi ...
Code:

var missingDates = .....select new ... // sve isto kao u queryOne dodelim vrednosti i sada imam te dve kolekcije

I sada probam...
Code:

var t = queryOne.Union(missingDates); // ovo nece da prodje ni compile

A probao sam i queryOne da castujem u IList i onda napravio novi objekat..
Code:

var newObj = new { sve isto kao sto je dodato u queryOne };

I probao da ovo dodam u listu pukne neki error na dodavanju prijavljuje...
Code:

The value "System.Linq.Enumerable+WhereSelectEnumerableI....f__AnonymousType9...and cannot be used in this generic collection.
Parameter name: value

Malo mi gori pod nogama pa ako neko ima ideju sta da uradim nek se javlja :(
Re: LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 09:50 · pre 194 meseci #2
izlgeda kao da dva anonymous new generisu dva razlicita tipa, to mozes lako proveriti debuggerom (vidi oba IQueryable<T> sta je T)

jedno od resenja je da ne koristis anonymous tipove, deklarisi klasu koja ima polja koja ti trebaju i uradi select new MojaKlasa onda ce T uvek biti isto.

Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 10:13 · pre 194 meseci #3
Kada krenem kroz debug imam...
Code:

queryOne = {System.Linq.Enumerable+<JoinIterator>d__61`4[XXX.YYY.BLL.Order,XXX.YYY.BLL.OrdersStatus,System.Int32,<>f__AnonymousTypea`2[XXX.YYY.BLL.Order,XXX.YYY.BLL.OrdersStatus]].Join(value(XXX.YYY.BLL...

queryTwo = {System.Linq.Enumerable+WhereSelectEnumerableIterator`2[XXX.YYY.BLL.Order,<>f__AnonymousType9`19[System.String,System.String,System.Int32,System.String,System.Nullable`1[System.DateTime],System.String,System.String,System.String,System.Strin...

Predpostavljam da je to, to. Razlikuju se (ne znam jos ucim LINQ). Morao sam da zamenim XXX.YYY... ali dobro to su namespace-ovi nebitno je.

Mislis da ne koristim 'var'? A sta da koristim? Jer code koji vec postoji koristi ovaj pristup (var). Vec postoji klasa "Order" ali zbog silnih dodataka morali su ranije da koriste LINQ sada ja samo nastavljam :)
Re: LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 10:37 · pre 194 meseci #4
ma jok, var je ok, problem je sto ne moze da merguje liste instanci dva razlicita tipa a to je posledica anonymous tipova koji iako sadrze ista polja nisu isti tip. ako mergujes List<Anonmous1> i List<Anonmous2> sta bitrebao da bude rezultat ;)

Dakle samo umesto sto projektujes u anonymous tipove projektuj u istu custom klasu, umesto


Code:

var result = from u in db.users
             where nesto
             select new  {ID = u.id, Name = u.name };
var result2 = from u in db.users
             where nesto2
             select new  {ID = u.id, Name = u.name };
// merge result i result2 ne radi


ide

Code:

class User { int ID {get; set;} string Name { get; set; }}

var result = from u in db.users
             where nesto
             select new User {ID = u.id, Name = u.name };
var result2 = from u in db.users
             where nesto2
             select new User {ID = u.id, Name = u.name };
// merge result i result2 


jedini downside je sto moras da deklarises User klasu

primer sam lupio jer nisi izneo ceo svoj kod, ali pretpostavljam da vidis na sta ciljam
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 11:15 · pre 194 meseci #5
Citat:
Valerij Zajcev: Kada krenem kroz debug imam...
Code:

queryOne = {System.Linq.Enumerable+<JoinIterator>d__61`4[XXX.YYY.BLL.Order,XXX.YYY.BLL.OrdersStatus,System.Int32,<>f__AnonymousTypea`2[XXX.YYY.BLL.Order,XXX.YYY.BLL.OrdersStatus]].Join(value(XXX.YYY.BLL...

queryTwo = {System.Linq.Enumerable+WhereSelectEnumerableIterator`2[XXX.YYY.BLL.Order,<>f__AnonymousType9`19[System.String,System.String,System.Int32,System.String,System.Nullable`1[System.DateTime],
System.String,System.String,System.String,System.Strin...

Predpostavljam da je to, to. Razlikuju se (ne znam jos ucim LINQ). Morao sam da zamenim XXX.YYY... ali dobro to su namespace-ovi nebitno je.

Mislis da ne koristim 'var'? A sta da koristim? Jer code koji vec postoji koristi ovaj pristup (var). Vec postoji klasa "Order" ali zbog silnih dodataka morali su ranije da koriste LINQ sada ja samo nastavljam :)



Evo da nadopunim Miljana sa kratkim sadrzajem vezanim za ovo tvoje. Mozda ti pomogne u razumijevanju i sprijeci
muke u buducnosti :)

http://www.speedyshare.com/files/25033007/CSharp30.zip
Re: LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 13:14 · pre 194 meseci #6
Citat:
mmix: ma jok, var je ok, problem je sto ne moze da merguje liste instanci dva razlicita tipa a to je posledica anonymous tipova koji iako sadrze ista polja nisu isti tip. ako mergujes List<Anonmous1> i List<Anonmous2> sta bitrebao da bude rezultat ;)

Dakle samo umesto sto projektujes u anonymous tipove projektuj u istu custom klasu, umesto


Code:

var result = from u in db.users
             where nesto
             select new  {ID = u.id, Name = u.name };
var result2 = from u in db.users
             where nesto2
             select new  {ID = u.id, Name = u.name };
// merge result i result2 ne radi


ide

Code:

class User { int ID {get; set;} string Name { get; set; }}

var result = from u in db.users
             where nesto
             select new User {ID = u.id, Name = u.name };
var result2 = from u in db.users
             where nesto2
             select new User {ID = u.id, Name = u.name };
// merge result i result2 


jedini downside je sto moras da deklarises User klasu

primer sam lupio jer nisi izneo ceo svoj kod, ali pretpostavljam da vidis na sta ciljam


To je resilo problem :)
Imam jos jedno pitanje. Kada kazem...
Code:

var merge = res1.Union(res2);

Dobijem samo da se ova dva rezultata spoje u jedan.
res1 - datumi iz baze
res2 - datumi koji ne postoje u bazi, a postoje izmedju i trebam da ih dodam
Dakle da li moze nekako u LINQ u toku izvrsavanja merge = ... da se proveri da li datum postoji u res1 ili ne?
Re: LINQ problem sa dodavanjem novih vrednosti 05.11.2010. u 13:27 · pre 194 meseci #7
Mozes

Union ima overload koji prima IEqualityComparer<T>

Napravis comparer klasu koji poredi User na osnovu datum polja (opet lupam)

Code (csharp):
class MojUserEqualityComparer: IEqualityComparer<User>
{
    public bool Equals(User b1, User b2)
    {
        return b1.datum == b2.datum;
    }

    public int GetHashCode(User u)
    {
        return u.datum.GetHashCode();
    }
}


onda instancu toga ubacis u Union

Code (csharp):
var merge = res1.Union(res2, new MojUserEqualityComparer ());

Iskreno nemam pojma zasto ovde ne postoji labmda overload, ali ajde.
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: LINQ problem sa dodavanjem novih vrednosti 06.11.2010. u 02:01 · pre 194 meseci #8
>>Iskreno nemam pojma zasto ovde ne postoji labmda overload, ali ajde.

Pa hajde da ga napravimo :)

Default implementacija IEqualityComparer koja prima lambde:
Code:

    public class DefaultEqualityComparer<T> : IEqualityComparer<T>
    {
        private Func<T, T, bool> _equalsFunc;
        private Func<T, int> _getHashCodeFunc;

        public DefaultEqualityComparer(Func<T, T, bool> equalsFunc, Func<T, int> getHashCodeFunc)
        {
            _equalsFunc = equalsFunc;
            _getHashCodeFunc = getHashCodeFunc;
        }

        public bool Equals(T x, T y)
        {
            return _equalsFunc(x, y);
        }

        public int GetHashCode(T obj)
        {
            return _getHashCodeFunc(obj);
        }
    }


Extension metod:
Code:

    public static class Extensions
    {
        public static IEnumerable<T> Union<T>(this IEnumerable<T> enumerable, IEnumerable<T> second, Func<T, T, bool> equalsFunc, Func<T, int> getHashCodeFunc)
        {
            return enumerable.Union(second, new DefaultEqualityComparer<T>(equalsFunc, getHashCodeFunc));
        }
    }


upotreba:

Code:

var merge = res1.Union(res2, (x, y) => x.Datum == y.Datum, (x) => x.Datum.GetHashCode());
Potpis
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
Re: LINQ problem sa dodavanjem novih vrednosti 06.11.2010. u 07:22 · pre 194 meseci #9
Dal union uopste poziva hasher? Kad si vec napravio extension zabodi breakpoint :)
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: LINQ problem sa dodavanjem novih vrednosti 12.11.2010. u 11:49 · pre 194 meseci #10
Ok, sada sam video da ivde postoji jedan problem.
Code:

var res1 = ....linq...select new OrderHelper{...
var res2 = ....linq...select new OrderHelper{...
var merge = res1.Union(res2, new OrderEqualityHelper());

U ovom trenutku, u obe liste je Order helper objekat, stim sto res1 sadrzi objekte koje imaju podatke, a res2 sadrzi isto samo sto su od propertija popunjani samo datumi. U debug-u provereno. Ali kada udje u OrderEqualityHelper() u metodi Equals oba parametra su isti. Naisao sam na dodatni problem pri spajanju pa sam ovo video. Moja pretpostavka je da bi u oh2 trbeala sva polja osim datuma da budu null osim datuma...?
Code:

public class OrderEqualityComparer : IEqualityComparer<OrderHelper>
    {
        public bool Equals(OrderHelper oh1, OrderHelper oh2)
        {
            return (oh1.Date == oh2.Date);
        }
Re: LINQ problem sa dodavanjem novih vrednosti 12.11.2010. u 11:53 · pre 194 meseci #11
Nisam bas razumeo sta je isto?

oh1 i oh2 su ista referenca?

Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: LINQ problem sa dodavanjem novih vrednosti 12.11.2010. u 12:07 · pre 194 meseci #12
Code:

var unionResult = result1.Union(result2, new OrderEqualityComparer()); 

Na ovoj gore liniji
result1 sadrzi listu objekata cija su polja:
ID = 5, TypeID = 12, Date = 1/1/2010 ...
result2 sadrzi listu objekata cija su polja:
ID = 0, TypeID = 0, Date = 8/8/2010 ...
Ali kada udjem u metodu "Equals", kapiram da bi oh1 treba da sadrzi objekat iz result1, a oh2 objekat iz result2. Ali nije tako. Svaki objekat i u oh1 i u oh2 ima sve podatke kao da je ista lista :(
Re: LINQ problem sa dodavanjem novih vrednosti 15.11.2010. u 08:01 · pre 194 meseci #13
Jel sigurno svaki put?

Moze da bude da od dve liste pravi trcecu tako sto prvo ubaci elemente prve pa elemente druge?
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: LINQ problem sa dodavanjem novih vrednosti 22.11.2010. u 07:22 · pre 193 meseci #14
Citat:

Jel sigurno svaki put?

Sory sto nisam odgovorio... Da svaki put se nekako ubace neki podaci u drugu listu i onda umesto da tamo budu samo datumi ono budu i datumi sa nekim pdoacima iz prve liste, nisam ukapirao sto. Ali problem sam resio drugacije posto su mi trebali nedostajuci datumi odradio sam ovako nesto, i radi.
Code:

 var range = Enumerable.Range(0, (int)(maxDate - minDate).TotalDays + 1)
                                            .Select(i => minDate.AddDays(i));

 var missing = range.Except(onlyDatesFromResult1List);
 List<DateTime> missingDatesList = missing.ToList();
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme