是否可以创建一个将项添加到实体框架dbset的通用方法?

时间:2013-06-05 15:56:41

标签: c# entity-framework generics entity-framework-5

我以前没有使用Entity Framework或泛型,并且在减少代码方面遇到了一些困难。

我正在解析一个文本文件来加载10个查找表,其中的数据可能会在每晚更改。文本文件具有“类型”的标题,后跟键/值集的列表。我有这个完美的工作,但我想重构代码来清理它,并希望使用泛型方法来实现这一点,以便我可以减少重复的代码。

我已经解析为泛型方法,但我无法弄清楚如何以通用方式将实体添加到上下文中。我必须遍历每种类型的实体列表并将它们添加到上下文中:

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

更新:以上工作正常,但似乎无法添加上下文。

我尝试了一些不同的东西,但是当我尝试对上下文进行泛化时似乎仍然会出现此错误:

  

类型'T'必须是引用类型才能在泛型类型的方法中将其用作参数'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>();
}

1 个答案:

答案 0 :(得分:21)

我目前的项目中有一个通用存储库。这是它的添加方法:

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

其中dbDbContext对象本身。 where T : class修复了有关引用类型的错误。没有它,您可以将任何类型传递为T,包括boolstruct,或DbSet.Add()无法处理的任何值类型。 where指定T必须是一个类,它是一个引用类型,因此允许。