2013-06-05 2 views
7

Я раньше не работал с Entity Framework или generics, и мне сложно сбить код.Возможно ли создать общий метод для добавления элементов в dbset-структуру сущности?

Я разбираю текстовый файл, чтобы загрузить 10 таблиц поиска с данными, которые могут быть изменены ночью. Текстовые файлы имеют заголовок для «type», за которым следует список наборов ключей/значений. У меня это работает отлично, но я хотел бы реорганизовать код для его очистки и хотел бы использовать общие методы для этого, чтобы я мог уменьшить дублированный код.

Я получил синтаксический анализ до общего метода, но мне не удалось выяснить, как получить сущности, добавленные в контекст общим способом. Я должен перебрать список сущностей для каждого типа и добавить их в контексте:

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; 
} 

Update: выше работает отлично, но не могу показаться, чтобы получить добавил контекст.

Я попробовал несколько разных вещей, но, кажется, продолжаю получать эту ошибку, когда я пытаюсь родовым до контекста:

типа «Т» должен быть ссылочным типом для того, чтобы использовать его в качестве параметр «T» в методе общего типа.

Последнее, что я попытался было добавить родовое GetDbSet в контексте:

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

Но я получаю ту же ошибку в мой контроллер, добавив этот код в метод GetItems:

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

Попробуйте добавить ограничение «где T: класс» к вашему методу GetItems – jure

+0

Это не помогает с добавлением функции .Add . В настоящее время работает GetItems, но я не могу использовать контекст, такой как 'context.Set () .Add (item);' – Warheft

+0

Вам нужно одинаковое ограничение для обоих методов. Если для параметра «Добавить » существует ограничение класса, то метод GetItems, который вызывает «Добавить», также должен иметь ограничение «class». – jure

ответ

17

У меня есть общий репозиторий в моем текущем проекте. Это его способ добавить:

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

где db является сам DbContext объект. where T : class исправляет эту ошибку в отношении типов ссылок. Без него вы можете передать любой тип в виде T, включая bool или struct, или любой тип значения, который DbSet.Add() не может справиться. where указывает, что T должен быть классом, который является ссылочным типом и поэтому разрешен.

+0

Хороший и чистый ответ –

+0

Это работает для репозитория, но я все еще получаю сообщение об ошибке, если попытаюсь вызвать его в GetItems следующим образом: 'context.Set () .Add (item);' или 'context.Add (item); ' – Warheft

+0

Выяснил это.Это проблема с наследованием с использованием интерфейса вместо конкретного типа. Теперь мне просто нужно немного изменить свои модели. Спасибо. – Warheft

Смежные вопросы