- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
使用工作单元和存储库模式,我有以下内容:
public interface IDatabaseFactory<C> : IDisposable
{
C Get();
void Set(string connectionString);
}
public interface IUnitOfWork<C>
{
ICustomerRepository Customers { get; }
//etc...
void Commit();
void ChangeDatabase(string connectionString);
string GetConnectionString(Database database);
}
public interface ICustomerRepository : IRepository<Customer> { }
和实现:
public class CustomerRepository : Repository<MyDbContext, Customer>, ICustomerRepository
{
public CustomerRepository (IDatabaseFactory<MyDbContext> databaseFactory)
: base(databaseFactory) { }
}
public class UnitOfWork<C> : IUnitOfWork<C> where C : DbContext, IMyDbContext
{
private readonly IDatabaseFactory<C> databaseFactory;
private C dataContext;
public UnitOfWork(IDatabaseFactory<C> databaseFactory)
{
this.databaseFactory = databaseFactory;
}
private ICustomerRepository customerRepository;
public ICustomerRepository Customers
{
get { return customerRepository?? (customerRepository = new CustomerRepository((IDatabaseFactory<MyDbContext>)databaseFactory)); }
}
private void ClearRespositories()
{
customerRepository = null;
}
protected C DataContext
{
get { return dataContext ?? (dataContext = databaseFactory.Get()); }
}
public string GetConnectionString(Model.Database database)
{
}
public void ChangeDatabase(string connectionString)
{
}
public void Commit()
{
}
}
我的模型有不少于 250 个主要实体,使用上述模式,需要相同数量的存储库,并且每个实体都是工作类单元中的一个属性。
我典型的服务层类是:
public class CustomerService : BaseService, ICustomerService
{
private ICustomerRepository customerRepository;
public CustomerService(IUnitOfWork<MyDbContext> unitOfWork) : base(unitOfWork) { }
public override void ChangeDatabase(string connectionString)
{
base.ChangeDatabase(connectionString);
customerRepository = unitOfWork.Customers;
}
}
我的应用程序有一个数据库上下文,这个上下文用于不同的数据库(使用相同的上下文)。当用户登录系统时,他可以选择一个数据库,这将相应地设置 uow 类的数据上下文。
我已将存储库添加到 UoW 类,以便所有存储库都具有相同的 uow。
这是正确的方法还是有更好的方法?
最佳答案
您可以使用通用存储库模式。这可以通过非常具体的域查询进行扩展。然后,您的 DI 容器可以创建您需要的特定存储库,您可以针对所有数据类对其进行操作。
如果对代码有任何疑问,请随时提出。
我会给你我的 VB.net 代码,希望它有用:
这是您将要使用的界面。保存和检索您的类(它们必须从 IEntity 继承)
Public Interface IRepository
Function GetEntity(Of T As {EntityObject, IEntity})(id As Integer) As T
Function GetAll(Of T As {EntityObject, IEntity})() As IEnumerable(Of T)
Sub Add(Of T As {EntityObject, IEntity})(entity As T)
Sub Remove(Of T As EntityObject)(entity As T)
Sub Attach(Of T As EntityObject)(entity As T)
Sub Update(Of T As {EntityObject, IEntity})(entity As T)
Function ExecuteQuery(Of T As {EntityObject, IEntity})(query As IQuery(Of T)) As IQueryResult(Of T)
Function ExecuteQuery(Of T As {EntityObject, IEntity}, TResult)(query As IQuery(Of T, TResult)) As IQueryResult(Of TResult)
End Interface
您必须在数据对象中实现的接口(interface)您还可以使用 other then int 进行 PK:
Public Interface IEntity
Property Id As Int32
End Interface
IQuery 对象,针对您的数据的特定查询实现它:
Public Interface IQuery(Of T As {EntityObject, IEntity})
Function Execute(ByVal objectSet As ObjectSet(Of T)) As IQueryResult(Of T)
End Interface
Public Interface IQuery(Of T As {EntityObject, IEntity}, TResult)
Function Execute(ByVal objectSet As ObjectSet(Of T)) As IQueryResult(Of TResult)
End Interface
您将使用的 QueryResult,它是可扩展的
Public Interface IQueryResult(Of T)
Function UniqueResult() As T
Function List() As IEnumerable(Of T)
End Interface
Public Class LinqResult(Of T)
Implements IQueryResult(Of T)
Private ReadOnly _query As IQueryable(Of T)
Public Sub New(query As IQueryable(Of T))
_query = query
End Sub
Protected Overridable Function ExpandQuery(query As IQueryable(Of T)) As IQueryable(Of T)
Return query
End Function
Public Function UniqueResult() As T Implements IQueryResult(Of T).UniqueResult
Dim result = ExpandQuery(_query).SingleOrDefault()
If result Is Nothing Then
Throw New EntityNotFoundException(Of T)()
End If
Return result
End Function
Public Function List() As IEnumerable(Of T) Implements IQueryResult(Of T).List
Return ExpandQuery(_query).ToList()
End Function
End Class
您的 ObjectcontextRepository,您的 IRepository 的实际实现
Public Class EntityObjectContextRepository
Implements IRepository
Private ReadOnly Property _context As ObjectContext
Get
Return UnitOfWork.Current
End Get
End Property
Public Sub Add(Of T As {EntityObject, IEntity})(entity As T) Implements IRepository.Add
_context.CreateObjectSet(Of T)().AddObject(entity)
End Sub
Public Sub Attach(Of T As EntityObject)(entity As T) Implements IRepository.Attach
_context.Attach(entity)
'_context.CreateObjectSet(Of T)().Attach(entity)
End Sub
Public Sub Update(Of T As {EntityObject, IEntity})(ByVal entity As T) Implements IRepository.Update
_context.CreateObjectSet(Of T)().Attach(entity)
_context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified)
End Sub
Public Function ExecuteQuery(Of T As {EntityObject, IEntity})(query As IQuery(Of T)) As IQueryResult(Of T) Implements IRepository.ExecuteQuery
Return query.Execute(_context.CreateObjectSet(Of T))
End Function
Public Function ExecuteQuery(Of T As {EntityObject, IEntity}, TResult)(ByVal query As IQuery(Of T, TResult)) As IQueryResult(Of TResult) Implements IRepository.ExecuteQuery
Return query.Execute(_context.CreateObjectSet(Of T))
End Function
Public Function GetAll(Of T As {EntityObject, IEntity})() As IEnumerable(Of T) Implements IRepository.GetAll
Return _context.CreateObjectSet(Of T).ToList().Where(Function(c) c.EntityState <> EntityState.Deleted)
End Function
Public Function GetEntity(Of T As {EntityObject, IEntity})(id As Integer) As T Implements IRepository.GetEntity
Dim entity = _context.CreateObjectSet(Of T)().SingleOrDefault(Function(x) x.Id = id)
Return ReturnEntityWhenItExists(entity)
End Function
Public Sub Remove(Of T As EntityObject)(entity As T) Implements IRepository.Remove
_context.DeleteObject(entity)
End Sub
Private Function ReturnEntityWhenItExists(Of T As {EntityObject, IEntity})(ByVal entity As T) As T
If entity IsNot Nothing AndAlso entity.EntityState <> EntityState.Deleted Then
Return entity
End If
Throw New EntityNotFoundException(Of T)()
End Function
End Class
包装这一切的工作单元:
Public Class UnitOfWork
Implements IDisposable
Private Shared _dataContext As ObjectContext
Public Shared ReadOnly Property Current As ObjectContext
Get
If _dataContext Is Nothing Then
Throw New UnitOfWorkException(ResourceRetriever.GetResource(Of String)("ExceptionUnitOfWorkNotInitializedMessage"))
End If
Return _dataContext
End Get
End Property
Public Sub New()
Me.New(New YourDataModelContainer())
End Sub
Public Sub New(ByVal objectContext As ObjectContext)
If _dataContext IsNot Nothing Then
Throw New UnitOfWorkException(ResourceRetriever.GetResource(Of String)("ExceptionUnitOfWorkAlreadyInitializedMessage"))
End If
_dataContext = objectContext
End Sub
Public Sub Complete()
If _dataContext Is Nothing Then
Throw New UnitOfWorkException(ResourceRetriever.GetResource(Of String)("ExceptionUnitOfWorkNotInitializedMessage"))
End If
_dataContext.SaveChanges()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
If _dataContext IsNot Nothing Then
_dataContext.Dispose()
_dataContext = Nothing
End If
End Sub
End Class
查询示例:
Public Class GetAllBuildingsQuery
Implements IQuery(Of DataAccess.Building, BuildingDto)
Public Function Execute(ByVal objectSet As ObjectSet(Of Building)) As IQueryResult(Of BuildingDto) Implements IQuery(Of Building, BuildingDto).Execute
Dim query = objectSet.Select(Function(g) New BuildingDto() With {.Description = g.Name, .Id = g.Id})
Return New LinqResult(Of BuildingDto)(query)
End Function
End Class
在服务调用中是如何实现的:
Public Class EmployeeService
Implements IEmployeeService
Private ReadOnly _repository As IRepository
Public Sub New(ByVal repository As IRepository)
_repository = repository
End Sub
Public Function GetAllEmployees() As IEnumerable(Of EmployeeOverviewDto) Implements IEmployeeService.GetAllEmployees
Dim employees = _repository.ExecuteQuery(EmployeeQueries.GetAllEmployeesForOverview()).List()
Return employees
End Function
End Class
关于C# Entity Framework 和存储库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22553375/
任何人都知道如何将内容从一个 Magnolia CMS 存储库(Jackrabbit 存储库)传输/迁移到我们的应用程序使用的另一个自定义 jacrabbit 存储库? 最佳答案 正如另一张海报所建议
Git 是否支持任何允许我直接从本地/工作树提交到远程存储库的命令?正常的工作流程至少需要一个“git add”来用文件内容的副本等填充对象数据库。 我知道这不是正常的、预期的 Git 工作流程。但我
我们正在将 Git 存储库移动到新服务器。迁移后我们显然可以只删除旧的存储库,所以当人们尝试推送或 pull 时他们会得到一个错误并在 wiki 上查找新的存储库 URL,但是是否有可能阻止 pull
我们有两个 Subversion 存储库,每个存储库都有一个项目。所以: svn://server/svn/project_a svn://server/svn/project_b 它们是独立的项目,
使用 maven/tycho 构建 Nodeclipse Eclipse 插件每个版本都有新的 p2 存储库。 发布是在 Bintray 上完成的不允许更新文件。所以每个版本都在它的文件夹中。 Bas
这听起来有点复杂,让我解释一下: Project_A 在它自己的 Mercurial 存储库中已经存在了一段时间。 Project_A 现在被 merge 到一个新的 super 项目 Super-P
这听起来有点复杂,所以让我解释一下: Project_A 已在其自己的 Mercurial 存储库中存在了一段时间。 Project_A 现在正在 merge 到一个新的 super 项目 Super
我想将我的所有文件从 Git Repo A 移动到 Git Repo B 并具有完整的历史记录。 Git B 已经包含另一个项目文件。我尝试了几种方法,例如 How to move files fro
我从 github 中托管的公共(public) git 存储库创建了一个裸存储库 (MY_LOCAL_REP): ~$ git clone --bare github 存储库已更新(创建了一个分支
工作 SVN 库 我正在启动一个 git 存储库来与 svn 存储库进行交互。 svn 存储库已设置并且工作正常,其中包含一个基本 README 文件的单次提交。 检查它工作正常: tchalvak:
我正在使用 spring boot 1.5.2 和 spring boot data redis 1.8。 我有两个@Id 注解,一个用于JPA,另一个用于redis hash。这里我想使用 JPA
我是 maven 的新手。我仍然无法理解它的概念。 例如,我正在寻找 com.extjs:gxt:jar:2.2.5 或 org.syslog4j:syslog4j:jar:0.9.46。我在任何 r
我已经阅读了很多关于存储库模式和服务层的作用的书,我(我认为)很清楚这两者之间的区别。但是现在有一个简单的问题让我挠头了一段时间。 我知道数据访问层如何负责...访问数据,因此典型的存储库可能具有插入
我是 Git/Smartgit 的新手。现在我不得不在 WIN 10 下配置一台新 PC。请问我如何将设置和存储库从旧 PC 导出/导入到新 PC? 非常感谢,问候, 本德 最佳答案 SmartGit
所以我最近开始在我的工作项目中使用存储库模式。我一直遇到同样的问题,我似乎无法找到答案: 可以将另一个存储库注入(inject)现有存储库吗?这样做有什么负面影响? 例如 : class Crawls
我有一个应用程序容器推送到 gitlab 容器注册表。我正在尝试将其作为容器部署到 azure web 应用程序服务中。我根据azure的文档尽我所能地进行了配置。但我不明白我错过了什么,因为 azu
我使用java框架来开发crud应用程序。这个框架被称为:“Cuba.Platform”。 我的问题是,我无法在古巴打开该项目。当我尝试在那里打开我的项目时,我遇到了这个问题: “存储库包含 http
我在我的数据层中有几个对数据库执行 CRUD 操作的存储库类。我不确定这种设计,因为大多数表都需要每个存储库一个专用类,一段时间后我最终会为数据库中存在的每个表得到很多存储库。我这样做是因为,当然,我
我正在重构一些代码,并将一些执行数据库 CRUD 操作的方法提取到它们自己的存储库类中。 我有几个问题,鉴于以下两种类型的对象存储在数据库中:用户和角色 我应该创建 IUserRepository 和
尝试在这里创建一个非常简单的存储库和服务层模式。 (.NET 4、C#、LINQ,尽管这个问题部分与语言无关)。注意:这只是研发。 我的目标是尽量减少服务层中方法定义的数量。 这是我的存储合约: in
我是一名优秀的程序员,十分优秀!