Is it possible to create a generic method for adding items to a entity framework dbset?

只谈情不闲聊 提交于 2019-12-05 17:49:22

问题


I have not worked with Entity Framework or generics before and am having some difficulty reducing my code.

I am parsing a text file to load 10 lookup tables with data that could possibly change nightly. The text files have a heading for the "type" followed by a list of key/value sets. I have this working perfectly, but I would like to refactor the code to clean it up and would like to use generic methods to accomplish this so I can reduce the duplicated code.

I have gotten the parsing down to a generic method, but I have not been able to figure out how to get the entities added to the context in a generic way. I have to loop over a list of the entities for each type and add them to the context:

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: The above works fine, but cannot seem to get the context added.

I have tried a few different things, but seem to keep getting this error when I try to generic up the context:

The type 'T' must be a reference type in order to use it as parameter 'T' in the generic type of method.

The last thing I tried was to add a generic GetDbSet to the context:

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

But I get the same error in my controller adding this code to the GetItems method:

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

回答1:


I have a generic repository in my current project. This is its add method:

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

where db is the DbContext object itself. The where T : class fixes that error about reference types. Without it, you could pass any type in as T, including bool or struct, or any value type, which DbSet.Add() can't handle. The where specifies that T must be a class, which is a reference type, and therefore allowed.



来源:https://stackoverflow.com/questions/16944527/is-it-possible-to-create-a-generic-method-for-adding-items-to-a-entity-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!