C# 使用DbContext作为存储库
目前我正在从事一个项目,在这个项目中,我们阅读、加工和储存产品。我们使用EntityFramework6读写MySql数据库 在构建原型并获取一些统计数据后,我们发现在数据库中存储新产品需要(相对)较长的时间。我被要求改进这一点,但我真的不知道最好的选择是什么 目前,每次读写都是在C# 使用DbContext作为存储库,c#,entity-framework,C#,Entity Framework,目前我正在从事一个项目,在这个项目中,我们阅读、加工和储存产品。我们使用EntityFramework6读写MySql数据库 在构建原型并获取一些统计数据后,我们发现在数据库中存储新产品需要(相对)较长的时间。我被要求改进这一点,但我真的不知道最好的选择是什么 目前,每次读写都是在中使用块进行的。因为这是我第一次使用EntityFramework6,所以我做了研究,大多数StackOverflow都说应该始终使用using块。所以我做了 它现在的样子的代码片段 public int GetSom
中使用块进行的。因为这是我第一次使用EntityFramework6,所以我做了研究,大多数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暴露于海量数据而不是单个数据插入,它的工作速度会更快。另外,在阅读了这个问题之后,我认为程序最好不要立即将数据写入数据库(因此,不要使用using
),而是创建一个简单的存储库来保存数据,并在一定时间后将其写入数据库。因为我愿意通过多个线程访问存储库
,所以我认为单例设计可以满足需要
但是有一个讨厌的要求;产品必须由特定的值匹配,并且产品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
}
实际上,有几个问题
- 使整个类线程安全是一项艰巨的任务吗?我是否需要为每个表添加一个锁才能这样做,还是有更聪明的方法
- 它真的会提高性能吗?上面的相关问题确实让我觉得是的
- 因为这不是推荐的方式,你们中的大多数人(可能)会不同意;有没有更好的方法来实现这一点
请注意,当前版本按原样工作。该程序需要处理大约250万个产品,唯一的瓶颈似乎是写入数据库。最后,我还读了一篇文章,清楚地告诉我如何使用它,但没有告诉我为什么应该或不应该使用它 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)
第二个值通常是如下所示的SQLParameter数组:
var parms = new List<SqlParameter>()
parms.Add(new SqlParameter { Name="Parm1", value = "myvalue" }).ToArray();
var parms=new List()
Add(新的SqlParameter{Name=“Parm1”,value=“myvalue”}).ToArray();
现在,这个混合解决方案的优点是,您可以获得绝对最快的SQL响应,因为您直接访问SQL,但是您可以使用强类型模型返回结果
允许任何类型的查询、更新、插入、删除
这种混合方法使您最接近SQL层,而仍然保持在EF内。返回的任何集合仍允许使用LINQ。这对我来说是两个世界中最好的一个。一堆好问题!首先,您正在正确地创建存储库,因为它至少可以减少数据库的不断打开和关闭。我不太熟悉DB层的锁定,但我建议DB锁定表或行是很常见的事情。在应用程序层锁定也是可以的,并且您走在了正确的轨道上。唯一的问题是它可能太宽了。但我确实有一些非常好的消息要告诉你,我将发布一个答案,因为它可以消除问题,同时为你提供最好的EF和SQL世界。由于我愿意通过多个线程访问存储库,我认为单线程设计将满足你的要求。单例并不能保证它是线程安全的。您必须在整个代码中明确地这样做,就像使用实例一样。请参阅问题以供参考。据我所知,EF并不是为大批量操作而构建的。您也可以使用它来提高性能。它还有其他瓶颈,您需要跟踪更改。。但如果只是添加新的实体,我认为应该可以。CodePlex上还有一个批量插入的项目,使整个类线程安全是一项困难的任务吗?我需要为每个表添加一个锁吗?还是有更聪明的方法我在这里找不到这个问题的答案。它真的会提高性能吗?我在这里找不到这个问题的答案。这个问题是关于通过EntityFramework添加到数据库的。sql select查询与此有什么关系?我看不出这个答案对OP有什么帮助。一些人会说是的,其他人会说“这取决于”首先,查询性能是查询编写方式的函数。有很多人知道EF在编写性能良好的查询方面的作用,但是,有更多的DBA使用SSM等工具了解查询性能。底线是,你离“金属”越近,事情发展得越快。如果速度是最重要的,那么直接与SQL接口是很好的。很抱歉,但我也没有把这看作是一个答案。。。也许你误解了我的问题?
var parms = new List<SqlParameter>()
parms.Add(new SqlParameter { Name="Parm1", value = "myvalue" }).ToArray();