🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: alt.pl.comp.lang.csharp
6 messages
6 total messages Started by skynet Fri, 13 Jul 2012 12:14
Linq + filter + lambda
#22407
Author: skynet
Date: Fri, 13 Jul 2012 12:14
21 lines
1694 bytes
Witam,

Mam potrzeba napisania rozszerzenia do Linq , które działało  by identycznie 
jak filtr w obiekcie DataTable.
Przekonwertowanie listy generycznej na tabele, przefiltrowanie jej i wynik 
umieścić z powrotem  w nowej liście generycznej
nie wchodzi obecnie w grę.
Obecnie zastanawiam się czy identyczną funkcjonalność  da się osiągnąć za 
pomocą linq i wyrażeń Lambda?
Założenia:
- Nazwy pól klasy są parametrami
- Obsługuje wszystkie operatory matematyczne
- Typ : string , liczba , DateTime
- Dla stringów wymagany jest dodatkowo Like.

Może ktoś w sieci wykonał taką robotę i kodem się podzielił :) Obecnie  za 
pomocą googla nie mogę niczego podobnego trafić
Albo Microsoft w jakimś namespace posiada taką funkcjonalność ?
Czy ktoś coś na ten temat może napisać ?

Robi
Re: Linq + filter + lambda
#22408
Author: Łukasz 'Maly' Ostrowski
Date: Fri, 13 Jul 2012 13:02
10 lines
1022 bytes
On Fri, 13 Jul 2012 14:14:49 +0200, skynet wrote:
> <snip>

Nie czaję. Pokaż jak sobie to wyobrażasz, nawet
w niekompilującym się pseudo-kodzie.


-- 
Pozdrawiam,
Łukasz 'Maly' Ostrowski.      http://l3v.pl/
Re: Linq + filter + lambda
#22409
Author: skynet
Date: Fri, 13 Jul 2012 16:12
64 lines
3031 bytes
Przysyłam fragment rozszerzenia dla metody Like.

public static IEnumerable<T> Like<T>(this IEnumerable<T> ListFilter, string 
PropertyFilter, string FilterValues)
       {
           ParameterExpression p = Expression.Parameter(typeof(T), 
PropertyFilter);
           var methodCall = Expression.Call(
               Expression.Constant(FilterValues, typeof(string)),
               typeof(string).GetMethod("Contains"),
               Expression.PropertyOrField(p, PropertyFilter)
           );
           return ListFilter.Where(Expression.Lambda<Func<T, 
bool>>(methodCall, p).Compile());
       }

Przykładowy obiekt
public class pracownik
   {
       public string imie { get; set; }
       public string Nazwisko { get; set; }
       public DateTime T { get; set; }

   }

Przykładowa list
List<pracownik> prac = new List<pracownik>()
          {
              new pracownik {imie="Robert",Nazwisko="Wysocki",T=new 
DateTime(2004,1,1)},
              new pracownik {imie="Jan",Nazwisko="Kowalski",T=new 
DateTime(2005,1,1)},
              new pracownik {imie="Pawel",Nazwisko="Mikulski",T=new 
DateTime(2006,1,1)}
          }

Wywołanie to (i to działa)
objBidn.DataSource = prac.Like <pracownik>("Nazwisko", "Kowalski");

Ale nie wiem dlaczego nie działa to
objBidn.DataSource = prac.Like <pracownik>("Nazwisko", "Kow");
przecież moje Like niczym się nie różni od zapisu
objBidn.DataSource = prac.Where(c => c.Nazwisko.Contains("Kow")); a to 
działa :)

To oczywiście jest początek tworzenia całej klasy Filtr . Tylko jestem 
ciekawy czy będę pionier przy tworzeniu takiego rozwiązania ?

Robi


Użytkownik "Łukasz'Maly' Ostrowski"  napisał w wiadomości grup 
dyskusyjnych:1ubd8djr158m6$.co3g7zldp3br.dlg@40tude.net...

On Fri, 13 Jul 2012 14:14:49 +0200, skynet wrote:
> <snip>

Nie czaję. Pokaż jak sobie to wyobrażasz, nawet
w niekompilującym się pseudo-kodzie.


-- 
Pozdrawiam,
Łukasz 'Maly' Ostrowski.      http://l3v.pl/ 
Re: Linq + filter + lambda
#22410
Author: Łukasz 'Maly' Ostrowski
Date: Fri, 13 Jul 2012 20:08
45 lines
2442 bytes
On Fri, 13 Jul 2012 18:12:29 +0200, skynet wrote:
> public static IEnumerable<T> Like<T>(this IEnumerable<T> ListFilter, string 
> PropertyFilter, string FilterValues)
>        {
>            ParameterExpression p = Expression.Parameter(typeof(T), 
> PropertyFilter);
>            var methodCall = Expression.Call(
>                Expression.Constant(FilterValues, typeof(string)),
>                typeof(string).GetMethod("Contains"),
>                Expression.PropertyOrField(p, PropertyFilter)
>            );
>            return ListFilter.Where(Expression.Lambda<Func<T, 
> bool>>(methodCall, p).Compile());
>        }
> 
> Wywołanie to (i to działa)
> objBidn.DataSource = prac.Like <pracownik>("Nazwisko", "Kowalski");

Przekręciłeś kolejność argumentów contains, zrobiłeś Expression który
robi:
FilterValues.Contains(PropertyFilter);

Dlatego "Kowalski".Contains("Kowalski") działa
ale "Kow".Contains("Kowalski") już nie.
;-).

Szybki switch i cyk:

public static IEnumerable<T> Like<T>(this IEnumerable<T> ListFilter, string
PropertyFilter, string FilterValues)
{
    ParameterExpression p = Expression.Parameter(typeof(T),
PropertyFilter);
    var methodCall = Expression.Call(
       Expression.PropertyOrField(p, PropertyFilter), 
       typeof(string).GetMethod("Contains"), 
       Expression.Constant(FilterValues, typeof(string)));
    return ListFilter.Where(Expression.Lambda<Func<T, bool>>(methodCall, p)
.Compile());
}


-- 
Pozdrawiam,
Łukasz 'Maly' Ostrowski.      http://l3v.pl/
Re: Linq + filter + lambda
#22411
Author: skynet
Date: Fri, 13 Jul 2012 21:01
52 lines
2856 bytes
Ach te przeciążenia :) ok dzięki ,ale chyba sporo pracy mnie czeka
Robi

Użytkownik "Łukasz'Maly' Ostrowski"  napisał w wiadomości grup 
dyskusyjnych:1do9gul9b8wca$.11qpbwn07jo9l.dlg@40tude.net...

On Fri, 13 Jul 2012 18:12:29 +0200, skynet wrote:
> public static IEnumerable<T> Like<T>(this IEnumerable<T> ListFilter, 
> string
> PropertyFilter, string FilterValues)
>        {
>            ParameterExpression p = Expression.Parameter(typeof(T),
> PropertyFilter);
>            var methodCall = Expression.Call(
>                Expression.Constant(FilterValues, typeof(string)),
>                typeof(string).GetMethod("Contains"),
>                Expression.PropertyOrField(p, PropertyFilter)
>            );
>            return ListFilter.Where(Expression.Lambda<Func<T,
> bool>>(methodCall, p).Compile());
>        }
>
> Wywołanie to (i to działa)
> objBidn.DataSource = prac.Like <pracownik>("Nazwisko", "Kowalski");

Przekręciłeś kolejność argumentów contains, zrobiłeś Expression który
robi:
FilterValues.Contains(PropertyFilter);

Dlatego "Kowalski".Contains("Kowalski") działa
ale "Kow".Contains("Kowalski") już nie.
;-).

Szybki switch i cyk:

public static IEnumerable<T> Like<T>(this IEnumerable<T> ListFilter, string
PropertyFilter, string FilterValues)
{
    ParameterExpression p = Expression.Parameter(typeof(T),
PropertyFilter);
    var methodCall = Expression.Call(
       Expression.PropertyOrField(p, PropertyFilter),
       typeof(string).GetMethod("Contains"),
       Expression.Constant(FilterValues, typeof(string)));
    return ListFilter.Where(Expression.Lambda<Func<T, bool>>(methodCall, p)
.Compile());
}


-- 
Pozdrawiam,
Łukasz 'Maly' Ostrowski.      http://l3v.pl/ 
Re: Linq + filter + lambda
#22412
Author: Łukasz 'Maly' Ostrowski
Date: Sat, 14 Jul 2012 05:36
18 lines
1481 bytes
On Fri, 13 Jul 2012 23:01:51 +0200, skynet wrote:
> Ach te przeciążenia :) ok dzięki ,ale chyba sporo pracy mnie czeka
> Robi

Porządkowo na przyszłość: Byłbym wdzięczny jakbyś poprawnie
cytował i odpisywał pod orginalnym postem. Odpisywanie nad
orginałem zaburza porządek czytania ;-).

Ponieważ zaburza kolejność czytania.
> Dlaczego?
>> Odpisywanie nad cytatami.
>>> Co najbardziej wkurza w internecie?

;-).

-- 
Pozdrawiam,
Łukasz 'Maly' Ostrowski.      http://l3v.pl/
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads