Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架:替换整个数据库集集合_C#_Entity Framework_Dbset - Fatal编程技术网

C# 实体框架:替换整个数据库集集合

C# 实体框架:替换整个数据库集集合,c#,entity-framework,dbset,C#,Entity Framework,Dbset,我有一个泛型类,它对类型为T的实体执行添加/更新。AddOrUpdate方法接收要操作的DbSet集合以及要在DbSet中添加或更新的项列表。ItemExists用于检查集合中是否已存在项。如果有,我们会更新。如果没有,我们补充。该方法本质上比较传入项的主键与表中的每个项,如果存在匹配项,则返回true以及数据库对象本身 对于记录数较少的表,该代码运行良好。但是,对于较大的表,ItemExists方法效率非常低。该方法使用一个foreach循环,该循环本身位于调用者方法中的另一个foreach循

我有一个泛型类,它对类型为T的实体执行添加/更新。AddOrUpdate方法接收要操作的DbSet集合以及要在DbSet中添加或更新的项列表。ItemExists用于检查集合中是否已存在项。如果有,我们会更新。如果没有,我们补充。该方法本质上比较传入项的主键与表中的每个项,如果存在匹配项,则返回true以及数据库对象本身

对于记录数较少的表,该代码运行良好。但是,对于较大的表,ItemExists方法效率非常低。该方法使用一个foreach循环,该循环本身位于调用者方法中的另一个foreach循环内,给出^2

一种更简单的方法是简单地使用contextDataSet.Containsitem,但这会引发一个异常,即无法创建类型为的常量值,因为EF无法将该类转换为SQL查询。所以这是不可能的

现在我真正的问题是:有没有办法用传入的IEnumerable替换整个DbSet?传入的IEnumerable绑定到视图上的datagrid,基本上包含所有项,因此从逻辑上讲,替换整个集合应该是安全的。非常感谢您的帮助

代码


作为一个方面的注释,您应该考虑将ItEMe存在重命名为半微软ISH TrimeTestNameCurror。在实体框架中,您是否为实体使用代理对象?不,我关闭代理生成。但是,如果需要,可以将其重新打开。这是一个windows应用程序或web应用程序。这些实体使用相同的上下文还是不同的上下文?WPF应用程序。PeformOperation每次都创建不同的上下文。
public void AddOrUpdate<I, P>(Expression<Func<I, P>> dbSetExpression, IEnumerable<T> itemsToUpdate)
            where I : DbContext, new()
            where P : DbSet<T>
{
    DataFactory.PerformOperation<I>(c =>
    {
        if (m_primaryKey == null && !TryFindPrimaryKey(c))
        {
            throw new ArgumentException("Primary key cannot be null.");
        }

        // Get the table name from expression passed in.
        string dbsetName = ((MemberExpression)dbSetExpression.Body).Member.Name;

        var propertyInfo = c.GetType().GetProperties().Single(p => p.Name == dbsetName);

        // Get the values in the table.
        DbSet<T> contextDataSet = propertyInfo.GetValue(c) as DbSet<T>;


        foreach (var item in itemsToUpdate)
        {

            // If the primary key already exists, we're updating. Otherwise we're adding a new entity.
            T existingItem;

            if (ItemExists(contextDataSet, item, out existingItem) && existingItem != null)
            {
                c.Entry(existingItem).CurrentValues.SetValues(item);
            }
            else
            {
                contextDataSet.Add(item);
            }
        }

        c.SaveChanges();
    });
}

private bool ItemExists(DbSet<T> itemInDbSet, T itemInList, out T existingItem)
{
    foreach (var dbItem in itemInDbSet)
    {
        // Get the primary key value in the database.
        var dbValue = dbItem.GetType().GetProperties().Single(
            p => p.Name == m_primaryKey).GetValue(dbItem);

        // Get the primary key value from the item passed in.
        var itemValue =
            itemInList.GetType().GetProperties().Single(
            p => p.Name == m_primaryKey).GetValue(itemInList);

        // Compare the two values.
        if (dbValue.ToString() == itemValue.ToString())
        {
            existingItem = dbItem;
            return true;
        }
    }

    existingItem = null;
    return false;
}