我最近了解了存储库和工作单元设计模式,并认为我将在新的EF4 MVC3项目中实现它们,因为抽象通常很好.
当我将它们添加到项目中时,我想知道果汁是否值得谚语挤压,给出以下内容:
我看到使用Repository模式的唯一真正好处是单元测试应用程序.抽象出数据存储似乎并不有用,因为我知道数据存储区不会改变,而且,EF4已经提供了一个非常好的抽象(我只是调用.AddObject(),它看起来像我在修改内存中集合,我只是调用.SaveChanges()已经提供了工作单元模式).
我是否应该费心实施这种抽象?我觉得必须有一些我遗漏的巨大好处,但我觉得我不需要沿着这条路走下去.我愿意相信; 有人可以提起诉讼吗?谢谢.
entity-framework unit-of-work repository-pattern asp.net-mvc-3
我正在设计一个ASP.NET MVC3应用程序,我希望在3层架构中明确区分关注点.我使用Fluent NHibernate作为ORM,Repository模式与NHibernate映射的实体一起使用.我想添加一个具有Unit Of Work模式的适当业务层,保留MVC部分仅用于表示(通过使用通过业务层映射到nHibernate实体的ViewModels). 本文很好地描述了组合的3层和MVC架构.
根据这个MVC +工作单元+存储库文章,我没有看到业务层的明显区别.工作单元类为每个存储库类型提供强类型的getter,它看起来适合业务层.但是,它暴露了一个Save方法,我认为它会转换为使用nHibernate的BeginTransaction和CommitTransaction方法.这引出了一些问题:
1)将事务控制暴露给MVC是一个好主意吗?交易控制应该在哪个阶段发生?在我看来,MVC不应该对交易负责,但如何避免这种情况?
2)是否应该有一些自动处理交易的方法? 此ActionFilter实现是半自动的,但事务控制显然位于MVC部分,而不是业务层.
3)UnitOfWork类与业务层类相同吗?
- 如果是这样,这是否意味着我们可以在其中添加自定义业务逻辑方法?
- 如果没有,我们是否将工作单元包含在包含业务逻辑方法的其他类中?
我感谢任何想法或例子.谢谢.
architecture asp.net-mvc design-patterns unit-of-work fluent-nhibernate
我在 .Net4.0 Web 表单(不是 MVC!)应用程序中使用 EF4.3.1。
我倾向于使用带有 IUnitOfWork 接口的存储库模式。但我想知道我是否遵循了最佳实践,尤其是因为我遵循的大多数示例都基于 MVC 应用程序。
我会说它只是一个小型网络应用程序,因此可能会影响解决方案的选择。
该解决方案目前有 3 个项目,Model、Logic 和 Site。模型包含 codefirst 实体和 IUnitOfWork 接口。逻辑包含存储库和服务层。站点显然包含网站、代码隐藏等。
我不使用任何第三方注入实用程序(ninject 等)。我用 IUnitOfWork 手动注入存储库,即
公共 BookingRepository(IUnitOfWork unitOfWork)
我不太清楚如何处理服务层,如果 IUnitOfWork 也存在于 Site 项目中,或者只存在于 Logic 和 Model 层中。
目前我将一个存储库和一个工作单元注入到一个服务中,即
公共预订服务(IUnitOfWork unitOfWork,IBookingRepository 存储库,IAppSettings appSettings)
但这意味着提交(保存到db)是在站点级别完成的,但我想知道是否应该在服务层完成。这也意味着,由于我的 IUnitOfWork 是在我的模型层中声明的,我还需要在我的站点中引用 Model。
我可以做什么更好?我做对了吗?哈哈
我正在尝试在我的MVC Web应用程序中实现工作单元/存储库模式.
由于DbContext本身是一个工作单元,我想将它与我自己的UOW混合用于测试和解耦目的(将业务层与EF分离).那么将我的DbContext内部包装成如下所示的UOW类是一个好主意吗?
为清晰起见,代码减少
public interface IUnitOfWork
{
void Save();
}
public MyContext : DbContext
{
// DbSets here
}
public UnitOfWork : IUnitOfWork
{
public MyContext myContext { get; set; }
void Save()
{
myContext.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我会调用UnitOfWork实例来执行数据操作.
非常感谢提前:-)
asp.net-mvc repository-design unit-of-work repository-pattern dbcontext
我有一个脚本将循环中的一些“A”类型的新实体保存到数据库中。但是循环会抛出一些关闭 entityManager 的异常。所以必须重开。它导致应该与每个“A”实体连接的另一个“B”类型的实体与 unitOfWork 分离。如何将“B”附加到 unitOfWork?这是一个例子:
public function insert( Array $items )
{
$B = $this->bRepository->findOneBy( ['name' => 'blog'] );
$result = [ 'errors' => [], 'saved_items' => [] ];
foreach( $items as $item )
{
try
{
$A = new Entity\A();
$A->create([
'name' => $item->name,
'B' => $B // Here is the problem after exception. $B is detached.
]);
$this->em->persist( $A );
$this->em->flush( $A );
$result['saved_items'][] = $item->name;
} catch( \Eception $e )
{
$result['errors'][] = 'Item ' . …Run Code Online (Sandbox Code Playgroud) 互联网上充满了关于UnitOfWork模式的信息; 即便如此也不例外.
我仍然不明白它.在我的理解中UnitOfWork = Transaction in DB.就这样; 仅此而已.
它是否正确?
我的困惑是由于它是如何在不同的ORMs中实现的.NHibernate使用ISession的不仅仅是更Transaction.Dapper把一切都留给你.
我的问题是关于设计模式,不考虑任何ORM或技术.
如果不仅仅是Transaction,请解释如何.
编辑1
参考此链接为在@大卫奥斯本答案建议.
工作单元会跟踪您在业务事务中可能影响数据库的所有操作.完成后,它会计算出因工作而需要更改数据库的所有操作.
因此,这意味着UnitOfWork是DBTransaction 和更多.
以下是其他责任: -
保持您在本次工作中更改,插入和删除的状态.
根据此状态,在工作完成后修改数据库.
虽然上面引用中没有明确提及,但它也可以控制查询的批处理.
我的理解现在正确吗?
我有 3 个实体:
文件夹 :
<?php
namespace CMS\ExtranetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Folder
*
* @ORM\Table(name="folder")
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(repositoryClass="CMS\ExtranetBundle\Repository\FolderRepository")
*/
class Folder
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="guid")
* @ORM\GeneratedValue(strategy="UUID")
*/
public $id;
// Used in NotificationListener
public $beforeRemoveId;
/**
* @ORM\OneToMany(targetEntity="Document", mappedBy="folder", cascade={"persist", "remove"})
*/
public $documents;
}
Run Code Online (Sandbox Code Playgroud)
文档 :
<?php
namespace CMS\ExtranetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Document
* @ORM\Entity(repositoryClass="CMS\ExtranetBundle\Repository\DocumentRepository")
* @ORM\Table(name="document")
* @ORM\HasLifecycleCallbacks
*/
class Document
{
/**
* @ORM\Id
* @ORM\Column(name="id", …Run Code Online (Sandbox Code Playgroud) 例如我有这个类:
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _context;
public IProductRepository Products { get; private set; }
public ICategoryRepository Categories { get; private set; }
public IPhotoRepository Photos { get; private set; }
public UnitOfWork(ApplicationDbContext context, IProductRepository productRepository,
ICategoryRepository categoryRepository, IPhotoRepository photoRepository)
{
_context = context;
Products = productRepository;
Categories = categoryRepository;
Photos = photoRepository;
}
public int Complete()
{
return _context.SaveChanges();
}
public Task<int> CompleteAsync()
{
return _context.SaveChangesAsync();
}
public void Dispose()
{
_context.Dispose();
}
public async …Run Code Online (Sandbox Code Playgroud) c# dependency-injection idisposable unit-of-work asp.net-core
我有一个MVC应用程序(EF6,SQL Server CE 4),我最近重构了添加一个UnitOfWork类和一个服务层(这样我可以使用DbContext每个请求一个,并成功执行事务).
以前,我使用Unity将存储库注入控制器.我的单元测试(对于控制器)设置简单 - 我只是模拟每个存储库,并将它们传递给控制器构造函数.
在重构之后,我现在使用Unity注入服务层(到控制器)和UnitOfWork(到服务层).服务层现在通过传递UnitOfWork.DbContext给存储库的构造函数来实例化每个存储库.
在我的单元测试中,我试图模拟UnitOfWork和ServiceLayer(并将模拟UnitOfWork对象传递给ServiceLayer的构造函数).但是,测试失败,说"在ControllerTest中TestFixtureSetup失败".
我认为这是由于我试图将UnitOfWork模拟传递给ServiceLayer模拟器,因此将非常感谢有关如何正确执行此操作的任何指导.
相关代码片段如下.
的UnitOfWork
public interface IUnitOfWork:IDisposable
{
void Save();
IDSMContext Context { get; }
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private IDSMContext _context;
public UnitOfWork()
{
_context = new IDSMContext();
}
public IDSMContext Context
{
get {return _context;}
}
public void Save()
{
_context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing) …Run Code Online (Sandbox Code Playgroud) entity-framework moq unity-container unit-of-work repository-pattern
下面的代码似乎使用这个:
var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider();
var repository = new FakeRepository();
var fake = new Fake
{
// etc.
};
using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString"))
{
repository.Insert(uow, fake);
uow.Commit();
}
Run Code Online (Sandbox Code Playgroud)
最终可能会进入服务层.我将不胜感激任何改进此代码的反馈.
public interface IUnitOfWork : IDisposable
{
void Commit();
Database Database { get; }
}
public interface IUnitOfWorkProvider
{
IUnitOfWork GetUnitOfWork(string connectionString);
}
public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
public IUnitOfWork GetUnitOfWork(string connectionString)
{
return new PetaPocoUnitOfWork(connectionString);
}
}
public interface IRepository<T>
{
void Insert(IUnitOfWork unitOfWork, T entity);
void Update(IUnitOfWork …Run Code Online (Sandbox Code Playgroud) unit-of-work ×10
asp.net-mvc ×2
c# ×2
doctrine-orm ×2
architecture ×1
asp.net-core ×1
dbcontext ×1
detach ×1
entity ×1
idisposable ×1
moq ×1
petapoco ×1
php ×1
repository ×1
symfony ×1