使用DbContext作为存储库

时间:2014-11-04 15:03:45

标签: c# entity-framework

目前我正在开展一个项目,我们在这个项目中阅读,处理和存储产品。我们正在使用Entity Framework 6来读取和写入MySql数据库。

在构建原型并获取一些统计数据后,我们发现在数据库中存储新产品需要(相对)很长时间。我被要求改进这个,但我无法弄清楚最好的选择是什么。

目前,每次读写都发生在using块中。由于这是我第一次使用Entity Framework 6,我做了我的研究,绝大多数StackOverflow说你总是使用using块。所以我做了。

现在看起来的代码摘要;

public int GetSomeId(string SomeStringToMatchWith)
{
    using (var db = new MyDbContext())
    {
        return db.SomeTable.Where(t => t.SomeString == SomeStringToMatchWith).FirstOrDefault().id;
    }
}

public void SaveSomeData(int SomeId)
{
    using(var db = new MyDbContext())
    {
        db.SomeTable.Add(new SomeTable{ Id = SomeId });
        db.SaveChanges();
    }
}

有人告诉我,如果MySql暴露给批量数据而不是单个数据插入,它的工作速度会更快。此外,在阅读this问题之后,我认为程序可能不会立即将数据写入数据库(因此,使用using),但要创建一个简单的Repository,它会在一定时间后保存数据并将其写入数据库。由于我愿意通过多个线程来访问Repository,我认为Singleton设计会满足。

但有一个令人讨厌的要求;产品必须与某些值匹配,可能发生产品#2与产品#1匹配。换句话说,我总是需要能够访问最新的数据。

我想到了这样的事情;

public class Repository
{
    private static readonly object Lock = new object();

    private MyDbContext context { get; set; }

    private Repository()
    {        
        context = new MyDbContext();
    }

    private static Repository _Instance;
    public static Repository Instance
    {
        get
        {
            if (_Instance == null)
            {
                lock(Lock)
                {
                    if(_Instance == null)
                    {
                        _Instance = new Repository();
                    }
                }                    
            }
            return _Instance;
        }
    }

    //This method is called once in a while
    public void Commit()
    {
        context.SaveChanges();
        context.Dispose();                //Get rid of entities
        context = new MyDbContext();      //Create a fresh DbContext
    }   

    //Other Read/Write methods  
}

实际上有几个问题;

  • 让整个班级线程安全是一项艰巨的任务吗?我是否需要为每个表添加锁定才能这样做,还是有更聪明的方法?
  • 它真的会提高性能吗?上面的链接问题确实让我觉得它确实如此。
  • 由于这不是推荐的方式,大多数人(可能)不同意;会有更好的方法来实现这个吗?

请注意,当前版本按原样运行。该程序需要处理大约2.5万个产品,唯一的瓶颈似乎是写入数据库。作为最后一点,我还阅读了Implementing the Repository and Unit of Work Patterns...,它清楚地告诉我该怎么做,但没有告诉我为什么我应该或不应该使用它。

1 个答案:

答案 0 :(得分:0)

EF非常强大,允许应用程序的设计者确定他们想要的深度!这是什么意思?这意味着您可以通过EF执行所有操作,也可以在需要时直接与SQL联系...以下是一些示例:

//The normal EF pattern is:
using(var db = new Myentities()){//do something here}

上面的方法有利于强大的输入,它允许完美的LINQ集成并产生非常好的(完美的)形成的查询。

//However you can use EF to hit SQL directly.
using(var db= new MyEntiteis()){ var stuff = db.DataBase<passInStrongType>(query,parms)

查询参数是一个字符串,带有像这样的参数占位符。

"Select * from Table where Field== @Parm1"  //works for inserts, updates and deletes too.

第二个值通常是SQLParameter数组,如下所示:

 var parms = new List<SqlParameter>()
 parms.Add(new SqlParameter { Name="Parm1", value = "myvalue" }).ToArray();

现在,这种混合解决方案的美化是你可以获得绝对最快的SQL响应,因为你直接使用SQL,但是你能够使用强类型模型返回结果。

允许任何类型的查询,更新,插入,删除...

这种混合方法让你最接近仍然保留在EF中的SQL层。返回的任何集合仍然允许LINQ。这对我来说是两个世界中最好的。