简体   繁体   English

存储库模式以从dbset.local或数据库获取数据

[英]Repository pattern to get data from dbset.local or database

I am writing a method which will loop over some data and create records in a database, the method makes use of a repository. 我正在编写一个方法,该方法将遍历一些数据并在数据库中创建记录,该方法利用了存储库。

Originally it was something like this: 最初是这样的:

///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
    }
}

Which worked but because it was saving to the DB with every iteration it was quite slow, so what I want to do is change it to something like 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]));
    }
    else
    {
       //Here I will get an instance of the entity that already exists and do some updates to it
    }

}

repo.Save();

So that the save is only done AFTER all of the entities have been created, so its one big DB insert rather than thousands. 因此只有在创建所有实体之后才进行保存,因此它是一个大的数据库插入而不是数千个。

The problem is that because the items have not been persisted back to my database the repo.MyItems.Count(x=>x.ID == i) doesn't bring anything back (Although the entities have been added to the dbset.Local collection. 问题在于,因为项目尚未持久化到我的数据库中,所以repo.MyItems.Count(x => x.ID == i)不会带回任何东西(尽管实体已添加到dbset.Local采集。

I suppose my question is how can I modify my repository to allow me to query the local collection AND the database - because that's the kicker, they may exist in the database OR they may have already been added to the repository and not inserted into the database. 我想我的问题是我该如何修改我的存储库以允许我查询本地集合和数据库-因为那很重要,它们可能存在于数据库中,或者它们可能已经添加到存储库中但没有插入数据库中。

The above is pseudo code, but kind of represents what I am doing, the repository method is something like 上面是伪代码,但是有点代表我在做什么,repository方法有点像

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

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

Again this is only a representation of what I have in the repo but it should give some idea of what I am going for. 再次,这只是我在回购中所拥有的东西的代表,但是它应该可以让我对我要去的事情有所了解。

If any one is interested, this is what I implemented and it seemed to work, however I ended up giving up on it as realised that this would pretty much be allowing "Dirty Reads" of the data which had a knock on effect on the rest of the system and we decided that the performance hit of multiple saves was more desirable than reworking big bits of the system - or implementing a repo that allows dirty reads... 如果有人感兴趣,这就是我实现的方法,并且似乎可行,但是我最终放弃了它,因为意识到这将几乎允许“脏读”数据,从而对其余数据产生影响系统的性能,因此我们认为,多次保存对性能的影响要比对系统的大部分进行重新处理更为可取-或实施允许脏读取的回购...

Note that GetSingle replaces the Count that I had in the pseudo code above. 请注意,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();
        }            
    }

If there is a better way to do this I would really like to know as this is an issue that I am probably going to encounter again and next time I might need to follow through with it! 如果有更好的方法,我真的很想知道,因为这是我可能会再次遇到的问题,下次我可能需要继续解决它!

I hope I understood the problem correctly, this is what I usually do: 我希望我正确理解了这个问题,这是我通常要做的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM