我为我的一个项目用UnitOfWork“我自己的上下文”实现了Repository模式,原因有几个
除了新的要求外,一切都很完美。我需要能够使用我的UnitOfWork来执行原始sql查询。
现在,如果我要使用实体,那将很容易。我可以逃避这样的事情
Context.Database.SqlQuery<SomeModel>("SELECT * FROM table WHERE id = @p0", someInt).ToList();
是的,我知道上面的代码不需要运行SqlQuery
。我在这里使用SqlQuery
来解释我想要做的事情。
但是因为我试图将我的代码与实体分离,所以我不能在我的应用程序中使用上面的代码。相反,我的工作单元需要为我提供一个API,它允许我完成某些事情。 “这里的要点是依赖于UnitOfWork”类而不是实体上下文。
这是我的任何UnitOfwork必须遵守的合同
public interface IUnitOfWork, IUnitOfWorkTransaction : IDisposable
{
IUserRepository Users { get; }
IAddressRepository Addresses { get; }
}
以下是上述合同的实施
public class UnitOfWork:IUnitOfWork { private readonly AppContext _context; public IUserRepository Users {get;私人集; } public IAddressRepository Addresses {get;私人集; }
public UnitOfWork(AppContext context)
{
_context = context;
Users = new UserRepository(_context);
Addresses = new AddressRepository(_context);
}
public UnitOfWork() : this(new AppContext())
{
}
public int Save()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
public IDatabaseTransaction BeginTransaction()
{
return new EntityDatabaseTransaction(Context);
}
}
现在,我想添加另一个合同,强制实现者添加执行SqlQuery的能力。
这是我开始做的事情
public DbRawSqlQuery<T> SqlQuery<T>(string sql, params object[] parameters)
{
return Context.Database.SqlQuery<T>(sql, parameters);
}
我的新合约将如下所示
public interface IUnitOfWorkSqlQuery
{
DbRawSqlQuery<T> SqlQuery<T>(string sql, params object[] parameters);
}
但是因为我试图将我的代码与实体分离,所以我不能在我的合同中使用DbRawSqlQuery<T>
,因为它是特定于实体的。所以我希望能够围绕DbRawSqlQuery
建立我自己的包装“泛型类”,即IDatabaseSqlQuery<T>
,我可以在合同中使用它。所以我的新合同将是这样的
public interface IUnitOfWorkSqlQuery
{
IDatabaseSqlQuery<T> SqlQuery<T>(string sql, params object[] parameters);
}
此时我有点失落,不知道我的IDatabaseSqlQuery<T>
应该是什么样子。如何围绕DbRawSqlQuery<T>
构建包装器?