实体框架+知识库+单位或工作问题 [英] entity framework + repository + unit or work question
问题描述
我正在考虑使用EF 4开始一个新项目,并浏览了一些文章,我找到了一篇有关EF的文章,其中包含存储库模式和工作单元( http:// blogs。 msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx )
I'm thinking about starting a new project using EF 4 and going through some articles, I found an article about EF with repository pattern and unit of work (http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx)
看那篇文章,它使用ObjectContext作为UnitOfWork,并将其传递到存储库。
Looking at that article, it uses the ObjectContext as the UnitOfWork and it passes it to the Repository.
我的问题是,如果我有2个ObjectContext,这意味着我将有2个工作单元,但实际上我希望在这2个上下文中执行的所有操作都成为一个工作单位,这种情况可能吗?我不想在每个上下文上调用save,我希望它是事务性的....而不使用transactionscope ...
My question is what if I have 2 ObjectContext which mean I will have 2 unit of work, but I actually wants all the operation perform on those 2 context to be one single unit of work, is this scenario possible? I don't want to call save on each context, I'd like it to be transactional .... without using transactionscope ...
例如,我有一个用于管理操作日志的上下文,另一个用于管理订单的上下文。可以说在我的业务层中,有一个名为AddOrder()的方法。 AddOrder()将使用订单上下文创建新订单,但还将使用操作日志上下文创建新的操作日志条目。由于这些是2个上下文,因此我必须在两个上下文上都调用save以提交....也许唯一的选择是只具有一个单独的上下文...。
For example, I have a context that manages Operation Log and another context that manages Orders. Lets say In my business layer, I have a method called AddOrder(). AddOrder() will use the order context to create a new order, but it will also use the operation log context to create a new operation log entry. Since those are 2 context, I'll have to call save on both context to commit .... maybe the only option is to have only one single context ....
编辑:我的意思是2个不同类型的上下文,例如:OperationalLogContext和OrderContext。
I meant 2 context of different types for example: OperationalLogContext and OrderContext.
推荐答案
是的-我相信这是可能的。
Yep - i believe it's possible.
最重要的是如何处理您的存储库。
The kicker is how handle your Repositories.
例如,每个存储库都应使用Context ..因此只需创建一个上下文并将其传递到每个存储库即可。
For example, each Repository should take a Context .. so just create one context and pass it to each repository.
(请输入代码!)很高兴你问:)
(code please!) Glad u asked :)
public interface IOrderRepository
{
IQueryable<Order> FindAll();
}
public interface IOperationLogRepository
{
IQueryable<OperationLog> FindAll();
}
public interface IUnitOfWork
{
void Commit();
}
。
public class SqlServerContext : ObjectContext, IUnitOfWork
{
public void SqlServerContext(string connectionString)
: base(connectionString)
{
}
public void Commit()
{
this.SaveChanges();
}
// Your other POCO's and stuff here ..etc..
}
。
public class OrderRepostiory : IOrderRepository
{
private readonly SqlServerContext _sqlServerContext;
public void OrderRepostiory(SqlServerContext sqlServerContext)
{
_sqlServerContext = sqlServerContext;
}
public IQueryable<Order> FindAll()
{
_sqlServerContext.Orders;
}
}
..最后是实例化。造成您的好男孩/女孩/彩虹独角兽,您将使用依赖注入..
.. and finally, instantiation. Cause your a good boy/girl/rainbow unicorn, you would be using Dependency Injection ..
public class SqlServerRegistry : Registry
{
public SqlServerRegistry(string connectionString)
{
For<SqlServerContext>()
.HybridHttpOrThreadLocalScoped()
.Use<SqlServerContext>()
.Ctor<string>("connectionString")
.Is(connectionString);
For<IOrderRepository>().Use<OrderRepository>();
For<IOperationLogRepository>().Use<OperationLogRepository>();
}
}
,由于SqlServerContext被定义为HttpOrThreadLocal,它将可以一次实例化并在多个存储库中 reused 。
and because the SqlServerContext is defined as HttpOrThreadLocal, it will be instantied ONCE and reused in multiple Repositories.
不知道或不了解DI / IoC吗?
Don't know or understand DI/IoC ?
然后这也将起作用。...
then this would also work....
private SqlServerContext _sqlServerContext;
private IOrderRepository _orderRepository;
private IOperationLogRepository _operationLogRepository;
[TestInitialize]
public void TestInitialise()
{
_sqlServerContext = new SqlServerContext(
ConfigurationManager.AppSettings["connectionString"]);
_orderRepository = new OrderRepository(_sqlServerContext);
_operationLogRepository= new OperationLogRepository(_sqlServerContext);
}
[TestMethod]
public void SomeTest()
{
// Arrange.
const int count = 10;
// Act.
var orders = _orderRepository.FindAll().Take(10).ToArray();
// Assert.
Assert.IsNotNull(orders);
CollectionAssert.AllItemsAreNotNull(orders);
Assert.AreEqual(count, orders.Length);
}
一次,这就是我刚刚输入的所有未经测试的代码正在考虑回答这个问题。
once more, that's all untested code which i just typed up, as I was thinking about answering this question.
HTH。
这篇关于实体框架+知识库+单位或工作问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!