Zmiana metody dla poprawy ergonomii kodu

0

Witam.

Piszę w tym momencie aplikację które głównie będzie wyświetlała dane. Użyłem EF do wyświetlania danych i napiałem metodę która wyciąga dane do datagridview. Na podstawie tej metody chciałbym stworzyć wyszukiwanie dokumentów WZ za pomocą textboxa. Ogólnie to się udało ale wiem że obie te metody da się jakoś przerobić na krótsze.

Ogólnie to metoda getdata() :


public void getdata()
        {
            
            EntitiesSito db = new EntitiesSito();

            var query = (from d in db.WZ_DWS_SITO
                         orderby d.WZ_DATA descending
                         group d by new { d.WZ, d.KUNNR, d.WZ_DATA } into grp
                         select new
                         {
                             grp.Key.WZ,
                             grp.Key.KUNNR,
                             grp.Key.WZ_DATA,
                             MATERIAL = grp.Count(),
                         }).ToList();

            datagridview.ItemsSource = query;

        }

Ma zwracać dane dotyczące dokumentów WZ do tego stworzyłem również event TEXBOXCHANGED który w momencie pojawienia sie tekstu wyszukuje WZ po ich numerze ale tak naprawdę różni sie ona tylko tym że w zapytaniu LINQ dodaję where coś tam. Nie znam się więc proszę o pomoc i wyjaśnienie jak mógłbym przerobić tą metodę getdata() aby następnie mógłbym w krótszej postaci użyć jej do mojej metody wyszukującej. Dobrze byłoby również wytłumaczenie mi koncepcji tworzenia takich metod jako że jestem początkujący i nie do końca ogarniam jeszcze myślenie koncepcyjne jeżeli chodzi o pisanie kodu.

Poniżej metoda dotyczące zmiany tekstu w texboxie :


 private void filtertxbox_TextChanged(object sender, TextChangedEventArgs e)
        {
            string numberofWZ = filtertxbox.Text;


            if (string.IsNullOrEmpty(numberofWZ) )
            {
                getdata();
            }
            else
            {
                EntitiesSito db = new EntitiesSito();

                var query2 = (from a in db.WZ_DWS_SITO
                              where a.WZ.Contains(numberofWZ)
                              orderby a.WZ_DATA descending
                              group a by new { a.WZ, a.KUNNR, a.WZ_DATA } into grp
                              select new
                              {
                                  grp.Key.WZ,
                                  grp.Key.KUNNR,
                                  grp.Key.WZ_DATA,
                                  MATERIAL = grp.Count(),
                              }).ToList();

                datagridview.ItemsSource = query2;

            }
        }

0

Ja bym stworzył klasę na wyniki i wyciągnął zapytanie do osobnej metody.

public class WzViewModel
{
	public string WZ {get;set;}
	public string KUNNR {get;set;}
	public string WZ_DATA {get;set;}
	public int MATERIAL {get;set;}
}

private WzViewModel SomeQuery(EntitiesSito db)
{
	return (from d in db.WZ_DWS_SITO
		 orderby d.WZ_DATA descending
		 group d by new { d.WZ, d.KUNNR, d.WZ_DATA } into grp
		 select new WzViewModel
		 {
			 grp.Key.WZ,
			 grp.Key.KUNNR,
			 grp.Key.WZ_DATA,
			 MATERIAL = grp.Count(),
		 });
}

private void filtertxbox_TextChanged(object sender, TextChangedEventArgs e)
{
	string numberofWZ = filtertxbox.Text;

	if (string.IsNullOrEmpty(numberofWZ) )
	{
		getdata();
	}
	else
	{
		EntitiesSito db = new EntitiesSito();

		var query2 = SomeQuery(EntitiesSito())
			.Where(x => x.WZ.Contains(numberofWZ))
			.ToList();

		datagridview.ItemsSource = query2;

	}
}

Innym rozwiązaniem jest przyjmowanie predykatu przez funkcję zwracającą query;

private IQueryable<WzViewModel> SomeQuery(EntitiesSito db, Expression<Func<TypEncjiEF, bool>> predicate = null)
{
	var source = predicate != null ? db.WZ_DWS_SITO.Where(predicate) : db.WZ_DWS_SITO;
	return (from d in source
		orderby d.WZ_DATA descending
		group d by new { d.WZ, d.KUNNR, d.WZ_DATA } into grp
		select new WzViewModel
		{
			grp.Key.WZ,
			grp.Key.KUNNR,
			grp.Key.WZ_DATA,
			MATERIAL = grp.Count(),
		});
}

IMHO to mniej eleganckie, ale z drugiej strony umożliwia podanie warunku dla oryginalnej encji, a nie tylko dla selectowanych pól.

0

Nie znam się więc pytam :) Dlaczego mam utworzyć nową klasę dla danych które mam w modelu danych utworzonych przez EF i EF utworzył mi już klasę dla tych danych ?

0

Dlatego, że sam tak robisz, tylko tworzysz klasę anonimową:

new {
	grp.Key.WZ,
	grp.Key.KUNNR,
	grp.Key.WZ_DATA,
	MATERIAL = grp.Count(),
}

Ale zwracając klasę anonimową z funkcji, musiałbyś zrzutować ją do object, a więc nie mógłbyś dostać się do jej pól w Where.
Co do tworzenia view modeli, to zaletą jest to, że masz klasę reprezentującą dokładnie te dane, które są potrzebne w widoku, co ułatwia późniejsze zrozumienie kodu i refaktoryzację. Co jeśli widok nie będzie ładowany z bazy tylko zewnętrznego API albo cache? Albo zmienią się pola w bazie? Dzięki osobnej klasie modyfikujesz tylko wczytywanie danych i bez dotykania widoków masz pewność, że będzie działać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1