2013-06-05 8 views
7

Nie pracowałem wcześniej z Entity Framework lub generics i mam trudności z redukcją mojego kodu.Czy jest możliwe utworzenie ogólnej metody dodawania elementów do zestawu dbtd struktury?

Parsuję plik tekstowy, aby załadować 10 tabel odnośników z danymi, które mogą być zmieniane co wieczór. Pliki tekstowe mają nagłówek "typ", po którym następuje lista zestawów klucz/wartość. Mam to działa doskonale, ale chciałbym, aby kod został oczyszczony i chciałbym użyć ogólnych metod, aby to osiągnąć, aby zredukować powielony kod.

Dostałem parsowanie do ogólnej metody, ale nie byłem w stanie wymyślić, w jaki sposób uzyskać jednostki dodane do kontekstu w sposób ogólny. Mam do pętli na listę podmiotów dla każdego typu i dodać je do kontekstu:

void Main() 
{ 
    switch (line.ToUpper()) 
    { 
     case "AREA": 
     { 
      List<Area> areaList = this.GetItems<Area>(file); 

      foreach (var element in areaList) 
      { 
       if (context.Area.Find(element.Id) == null) 
       { 
        context.Area.Add(element); 
       } 
      } 

      break; 
     } 
     case "CATEGORY": 
     { 
      List<Category> categoryList = this.GetItems<Category>(file); 

      foreach (var element in categoryList) 
      { 
       if (context.Category.Find(element.Id) == null) 
       { 
        context.Category.Add(element); 
       } 
      } 

      break; 
     } 
    } 
} 

private List<T> GetItems<T>(StreamReader reader) where T : ILookupData, new() 
{ 
    string line; 
    List<T> list = new List<T>();    

    while (reader.Peek() == ' ') 
    { 
     line = reader.ReadLine().TrimStart(); 
     string[] tokens = line.Split(new string[] { " - " }, 2, StringSplitOptions.None); 

     T item = new T(); 
     item.Id = Convert.ToInt32(tokens[0]); 
     item.Description = (string)tokens[1]; 

     list.Add(item); 
    } 

    return list; 
} 

Aktualizacja: Powyższe działa poprawnie, ale nie wydaje się uzyskać kontekst dodaje.

Próbowałem kilka różnych rzeczy, ale wydaje się wciąż otrzymuję ten błąd, gdy próbuję generycznego się kontekstu:

typu „T” musi być typu odniesienia w celu wykorzystania go jako parametr "T" w ogólnym rodzaju metody.

Ostatnią rzeczą, starałem się, aby dodać ogólny GetDbSet do kontekstu:

public DbSet<T> GetDbSet<T>() where T : class 
{ 
    return this.Set<T>(); 
} 

Ale pojawia się ten sam błąd w moim kontrolera dodając ten kod do metody GetItems:

using (MyContext context = new MyContext()) 
{ 
    var dbSet = context.GetDbSet<T>(); 
} 
+0

Spróbuj dodać ograniczenie "gdzie T: class" do metody GetItems – jure

+0

To nie pomaga w dodawaniu funkcji .Add . GetItems obecnie działa, ale nie mogę używać kontekstu takiego jak 'context.Set () .Add (item);' – Warheft

+0

Potrzebujesz tego samego ograniczenia dla obu metod. Jeśli Dodaj ma ograniczenie "class" niż metoda GetItems, która wywołuje Add, powinno również mieć ograniczenie "class". – jure

Odpowiedz

17

Mam ogólne repozytorium w moim bieżącym projekcie. To jest jego metoda add:

public void Add<T>(T newItem) where T : class 
{ 
    db.Set<T>().Add(newItem); 
} 

gdzie db jest sam obiekt DbContext. The where T : class naprawia ten błąd dotyczący typów referencji. Bez niego możesz przekazać dowolny typ jako T, w tym bool lub struct, lub dowolny typ wartości, którego nie może obsłużyć DbSet.Add(). Parametr where określa, że ​​T musi być klasą, która jest typem odniesienia i dlatego jest dozwolona.

+0

Przyjemna i czysta odpowiedź –

+0

To działa dla repozytorium, ale nadal otrzymuję błąd, gdy próbuję wywołać go w GetItems w ten sposób: 'context.Set () .Dodaj (element);' lub 'context.Add (pozycja); ' – Warheft

+0

Wyliczyłem to.Był to problem związany z dziedziczeniem z użyciem interfejsu zamiast typu konkretnego. Teraz po prostu muszę trochę zmodyfikować moje modele. Dziękuję Ci. – Warheft

Powiązane problemy