用于从dbset.local或数据库获取数据的存储库模式

时间:2015-01-07 12:11:48

标签: c# entity-framework repository-pattern

我正在编写一个循环数据并在数据库中创建记录的方法,该方法使用了存储库。

最初它是这样的:

///Lets assume that there is a string array called arr somewhere above this.
var repo = new ItemRepository();

for (int i = 0; i<1000; i++)
{
    if (repo.MyItems.Count(x=>x.ID == arr[i]) == 0)
    {
        //Doesn't Exist Create
        repo.MyItems.Add(new Item(arr[i]));
        repo.Save();
    }
    else
    {
       //Here I will get an instance of the entity that already exists and do some updates to it
    }
}

哪个有效,但是因为每次迭代它都保存到数据库中它很慢,所以我想做的就是把它改成这样的东西:

var repo = new ItemRepository();

for (int i = 0; i<1000; i++)
{
    if (repo.MyItems.Count(x=>x.ID == arr[i]) == 0)
    {
        //Doesn't Exist Create
        repo.MyItems.Add(new Item(arr[i]));
    }
    else
    {
       //Here I will get an instance of the entity that already exists and do some updates to it
    }

}

repo.Save();

所以只有在创建了所有实体之后才进行保存,所以它的一个大数据库插入而不是数千个。

问题是因为项目没有被持久化回我的数据库,repo.MyItems.Count(x =&gt; x.ID == i)并没有带回任何东西(尽管实体已经存在添加到dbset.Local集合。

我想我的问题是如何修改我的存储库以允许我查询本地集合和数据库 - 因为它是踢球者,它们可能存在于数据库中,或者它们可能已被添加到数据库中存储库,而不是插入数据库。

以上是伪代码,但有点代表我正在做的事情,存储库方法类似于

public int count(string val)
{
    IQueryable<T> data = _dbSet;

    return data.Count(x=>x.COLUMNNAME == val);
}

同样,这只是我在回购中的代表,但它应该让我知道我的目的。

2 个答案:

答案 0 :(得分:1)

如果有人感兴趣,这就是我实施的,它似乎有效,但是我最终放弃了它,因为意识到这几乎可以允许“脏读”数据产生连锁反应在系统的其余部分,我们认为多次保存的性能损失比重新处理系统的大部分更好 - 或者实现允许脏读的回购......

请注意,GetSingle会替换上面伪代码中的Count。

public T GetSingle(System.Linq.Expressions.Expression<Func<T, bool>> filter = null)
    {
        //Check the local collection first

        IQueryable<T> localEntities = _dbset.Local.AsQueryable();

        if (filter != null)
        {
            localEntities = localEntities.Where(filter);
        }

        if (localEntities.Count() > 0)
        {
            return localEntities.FirstOrDefault();
        }
        else
        {
            //A local version of this was not found - try the database.

            IQueryable<T> query = this._dbset;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            return query.FirstOrDefault();
        }            
    }

如果有更好的方法可以做到这一点,我真的很想知道这是一个我可能会再次遇到的问题,下次我可能需要继续使用它!

答案 1 :(得分:0)

我希望我能正确理解这个问题,这就是我通常做的事情:

        var repo = new ItemRepository();

        Int32 index = 0;
        Int32 localIndex = 0;
        while (index < arr.Length) {
            repo.MyItems.Add(new Item(arr[index]));
            index++;
            localIndex++;
            if (localIndex == 1000) {
                repo.Save();
                localIndex = 0;
            }
        }
        if (localIndex > 0) {
            repo.Save();
        }