是否有可能创建将项目添加到一个实体框架dbset一个通用的方法是什么? [英] Is it possible to create a generic method for adding items to a entity framework dbset?

查看:187
本文介绍了是否有可能创建将项目添加到一个实体框架dbset一个通用的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还没有与实体框架合作或仿制药之前和我有一些困难,减少了我的代码。



我解析一个文本文件加载数据10查找表那些可能改变每晚。文本文件具有针对类型,接着的键/值集合列表的标题。我有这方面的工作完美,但我想重构代码,把它清理干净,并想用通用的方法来做到这一点,所以我可以减少重复的代码。



我已经得到解析到一个通用的方法,但我一直无法弄清楚如何让实体添加到上下文中的一个通用的方法。我不得不遍历实体为每种类型的列表,并把它们添加到背景:

 无效的主要()
{
开关(line.ToUpper())
{
案AREA:
{
名单,LT;面积> areaList = this.GetItems<面积和GT;(文件);

的foreach(在areaList VAR元素)
{
如果(context.Area.Find(element.Id)== NULL)
{
上下文.Area.Add(元件);
}
}

中断;
}
案类:
{
名单,LT;类别>所属分类= this.GetItems<类别及GT;(文件);

的foreach(在所属分类VAR元素)
{
如果(context.Category.Find(element.Id)== NULL)
{
上下文.Category.Add(元件);
}
}

中断;
}
}
}

私人列表< T> GetItems< T>(StreamReader的读者),其中T:ILookupData,新的()
{
串线;
名单< T>名单=新名单< T>();

而(reader.Peek()=='')
{
线= reader.ReadLine()TrimStart();
的String []标记= line.Split(新的String [] { - },2,StringSplitOptions.None);
$ B $(B T)项目=新T();
item.Id = Convert.ToInt32(令牌[0]);
item.Description =(字符串)标记[1];

list.Add(项目);
}

返回列表;
}



更新:上述工作正常,但不能。似乎得到上下文添加



我已经尝试了一些不同的东西,但似乎不断得到这个错误,当我尝试仿制出上下文:




类型'T'必须是为了在通用型的方法来使用它作为参数T引用类型。




我试过的最后一件事是一个通用GetDbSet添加到背景:

 公共DbSet< T> GetDbSet< T>()其中T:类
{
返回this.Set< T>();
}



但我得到同样的错误在我的控制器将此代码添加到GetItems方法

 使用(MyContext上下文=新MyContext())
{
VAR dbSet = context.GetDbSet< ; T>();
}


解决方案

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

 公共无效添加< T>(T的newitem)其中T:类
{
db.Set< T>()添加(的newitem);
}



其中,分贝是在的DbContext 对象本身。在其中T:类修复有关引用类型的错误。没有它,你可以传递的任何的输入为T,包括布尔结构,或任何类型的值,其中 DbSet.Add()无法处理。在其中,指定T必须是一个类,它是一个引用类型,因此允许的。


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

解决方案

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.

这篇关于是否有可能创建将项目添加到一个实体框架dbset一个通用的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆