I don't know if there is a better way to use the DbContext
because it is not recommended to set is as static when working with WCF. So we are creating it each time we want to access the database.
我不知道是否有更好的方法来使用DbContext,因为在使用WCF时不建议将其设置为静态。所以我们每次想要访问数据库时都会创建它。
Knowing all the advantages of using Entity Framework, some become useless since we are recreating the DbContext
each time; and more may cause overhead since the process of creating big entity models is to be considered.
了解使用Entity Framework的所有优点,有些变得无用,因为我们每次都在重新创建DbContext;因为要考虑创建大实体模型的过程,所以可能会导致更多开销。
What is your opinion?
你有什么意见?
2 个解决方案
#1
51
Managing Lifetime
You're correct that a single static instance of DbContext
is usually not recommended:
你是正确的,通常不建议使用单个静态DbContext实例:
The more you use an ObjectContext, generally the bigger it gets. This is because it holds a reference to all the Entities it has ever known about, essentially whatever you have queried, added or attached. So you should reconsider sharing the same ObjectContext indefinitely.
您使用的ObjectContext越多,通常它就越大。这是因为它拥有对它所知道的所有实体的引用,基本上是您查询,添加或附加的任何实体。所以你应该重新考虑无限期地共享同一个ObjectContext。
These comments apply directly to the DbContext
, because it wraps wraps ObjectContext
to expose "simplified and more intuitive APIs." [see documentation]
这些注释直接应用于DbContext,因为它包装了ObjectContext以显示“简化且更直观的API”。 [见文件]
Cost of Construction
The overhead of creating the context is relatively low:
创建上下文的开销相对较低:
The reality is this cost is actually pretty low, because mostly it simply involves copying, by reference, metadata from a global cache into the new ObjectContext. Generally I don’t think this cost is worth worrying about ...
实际情况是,这个成本实际上非常低,因为它主要只涉及通过引用将全局缓存中的元数据复制到新的ObjectContext中。一般来说,我不认为这个成本值得担心......
The common way to work with a short-lived context is to wrap it in a using block:
使用短期上下文的常用方法是将其包装在using块中:
using(DbContext context = new SomeDbContext())
{
// Do work with context
}
To ease with testing, you may want to have your DbContext
implement some IDbContext
interface, and create a factory class ContextFactory<T> where T : IDbContext
to instantiate contexts.
为了便于测试,您可能希望让DbContext实现一些IDbContext接口,并创建一个工厂类ContextFactory
This allows you to easily swap any IDbContext
into your code (ie. an in-memory context for object mocking.)
这允许您轻松地将任何IDbContext交换到您的代码中(即用于对象模拟的内存上下文。)
Resources
- MSDN: How to decide on a lifetime for your ObjectContext
- MSDN:如何确定ObjectContext的生命周期
- *: Instantiating a context in LINQ to Entities
- *:在LINQ to Entities中实例化上下文
#2
1
The best practice for webdevelopment seems to be "one context per web request", see Proper Session/DbContext lifecycle management, when working with WCF this could be translated into one context per operation (i.e. one context per WCF method call).
Web开发的最佳实践似乎是“每个Web请求一个上下文”,参见正确的Session / DbContext生命周期管理,当使用WCF时,这可以被转换为每个操作一个上下文(即每个WCF方法调用一个上下文)。
There are different ways to achieve this but one solution, probably not recommended for different reasons, is to create a new instance of the context and pass it to the constructor of your business class:
有不同的方法可以实现这一点,但可能出于不同原因推荐的一个解决方案是创建上下文的新实例并将其传递给业务类的构造函数:
public void WCFMethod()
{
using (DBContext db = new DBContext())
{
BusinessLogic logic = new BusinessLogic(db);
logic.DoWork();
}
}
#1
51
Managing Lifetime
You're correct that a single static instance of DbContext
is usually not recommended:
你是正确的,通常不建议使用单个静态DbContext实例:
The more you use an ObjectContext, generally the bigger it gets. This is because it holds a reference to all the Entities it has ever known about, essentially whatever you have queried, added or attached. So you should reconsider sharing the same ObjectContext indefinitely.
您使用的ObjectContext越多,通常它就越大。这是因为它拥有对它所知道的所有实体的引用,基本上是您查询,添加或附加的任何实体。所以你应该重新考虑无限期地共享同一个ObjectContext。
These comments apply directly to the DbContext
, because it wraps wraps ObjectContext
to expose "simplified and more intuitive APIs." [see documentation]
这些注释直接应用于DbContext,因为它包装了ObjectContext以显示“简化且更直观的API”。 [见文件]
Cost of Construction
The overhead of creating the context is relatively low:
创建上下文的开销相对较低:
The reality is this cost is actually pretty low, because mostly it simply involves copying, by reference, metadata from a global cache into the new ObjectContext. Generally I don’t think this cost is worth worrying about ...
实际情况是,这个成本实际上非常低,因为它主要只涉及通过引用将全局缓存中的元数据复制到新的ObjectContext中。一般来说,我不认为这个成本值得担心......
The common way to work with a short-lived context is to wrap it in a using block:
使用短期上下文的常用方法是将其包装在using块中:
using(DbContext context = new SomeDbContext())
{
// Do work with context
}
To ease with testing, you may want to have your DbContext
implement some IDbContext
interface, and create a factory class ContextFactory<T> where T : IDbContext
to instantiate contexts.
为了便于测试,您可能希望让DbContext实现一些IDbContext接口,并创建一个工厂类ContextFactory
This allows you to easily swap any IDbContext
into your code (ie. an in-memory context for object mocking.)
这允许您轻松地将任何IDbContext交换到您的代码中(即用于对象模拟的内存上下文。)
Resources
- MSDN: How to decide on a lifetime for your ObjectContext
- MSDN:如何确定ObjectContext的生命周期
- *: Instantiating a context in LINQ to Entities
- *:在LINQ to Entities中实例化上下文
#2
1
The best practice for webdevelopment seems to be "one context per web request", see Proper Session/DbContext lifecycle management, when working with WCF this could be translated into one context per operation (i.e. one context per WCF method call).
Web开发的最佳实践似乎是“每个Web请求一个上下文”,参见正确的Session / DbContext生命周期管理,当使用WCF时,这可以被转换为每个操作一个上下文(即每个WCF方法调用一个上下文)。
There are different ways to achieve this but one solution, probably not recommended for different reasons, is to create a new instance of the context and pass it to the constructor of your business class:
有不同的方法可以实现这一点,但可能出于不同原因推荐的一个解决方案是创建上下文的新实例并将其传递给业务类的构造函数:
public void WCFMethod()
{
using (DBContext db = new DBContext())
{
BusinessLogic logic = new BusinessLogic(db);
logic.DoWork();
}
}