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

本文关键字:数据 存储 模式 获取 数据库 dbset local 用于 | 更新日期: 2023-09-27 18:36:38

我正在编写一个方法,该方法将循环访问一些数据并在数据库中创建记录,该方法利用了一个存储库。

最初是这样的:

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

因此,只有在创建所有实体后才能完成保存,因此它的一个大数据库插入而不是数千个。

问题是,因为这些项目尚未持久化回我的数据库存储库。MyItems.Count(x=>x.ID == i) 不会返回任何内容(尽管实体已添加到数据库集中。本地集合。

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

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

public int count(string val)
{
    IQueryable<T> data = _dbSet;
    return data.Count(x=>x.COLUMNNAME == val);
}

同样,这只是我在回购中所拥有的内容的表示,但它应该可以对我要做什么有所了解。

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

如果有人感兴趣,这就是我实现的并且它似乎有效,但是我最终放弃了它,因为我意识到这几乎允许对数据的"脏读取",这对系统的其余部分产生了连锁反应,我们决定多次保存的性能影响比重新设计系统的大部分更可取 - 或实现允许的存储库脏读...

请注意,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();
        }            
    }

如果有更好的方法来做到这一点,我真的很想知道,因为这是我可能会再次遇到的问题,下次我可能需要坚持下去!

我希望我正确理解了这个问题,这是我通常做的:

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