I wrapped Nhibernate session as the following.
public interface IDalSession : IDisposable
{
void MarkForRollBack();
void End();
IDalSession Start();
IDalSession StartWithTransaction();
T Save<T>(T entity);
T CreateQuery<T>(string query);
//ISession GetHibernateSession { get; }
}
I really want to use QueryOver as my main query.
QueryOver API looks impossible to be wrapped because it is huge.
One solution is to use the NHibernate ISession (GetHibernateSession) in all of the places I need to pull data. but it is very ugliy.
What is the workaround here?
How can I wrap QueryOver?
Thanks
Is this what you mean?
public interface IDalSession : IDisposable
{
void MarkForRollBack();
void End();
IDalSession Start();
IDalSession StartWithTransaction();
T Save<T>(T entity);
T CreateQuery<T>(string query);
IQueryOver<T,T> NewQueryOver<T>(); // check me out
//ISession GetHibernateSession { get; }
}
...
public IQueryOver<T,T> NewQueryOver<T>()
{
return Session.QueryOver<T>();
}
You may get some comments about hiding away anything NH from other layers, so for that its fine to be able to pass back a new linq to NH query as its IQueryable:
public virtual IQueryable<T> NewQuery<T>()
{
return Session.Query<T>();
}
but I personally prefer QueryOver API so I wrap my data access into concrete repositories. S#arp architecture does it nice:
Interface
Impl.
Related
Hello everyone I've successfully implemented the repository pattern with fluentNHibernate but i have one concern abount the ExposeConfiguration when I removed it all the methods works fine but when i adds it ,it resets the tables in the database. so i need you to take a look and give me any notes about the implementation so here is my unit of work class
public class UnitOfWork
{
public static ISession NhibernateHelper()
{
ISessionFactory _sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2012.ConnectionString(#"Data Source=WAAIL-PC\COMPUTERENGINEER;Initial Catalog=TSQL2012;User ID=sa;Password=12345678Ce").ShowSql())
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<UsersMap>())
//.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true)) //when i removed this line it doesn't
//remove the elements from the db
.BuildSessionFactory();
return _sessionFactory.OpenSession();
}}
and here is my repository pattern :
public class Repository<T> :IRepository<T> where T :BaseEntity
{
public Repository(/*IUnitOfWork unitOfWork*/)
{
//_unitOfWork = (UnitOfWork)unitOfWork;
}
public List<T> GetAll()
{
using (ISession Session = UnitOfWork.NhibernateHelper())
{
return Session.Query<T>().ToList();
}
}
public T GetById(int id)
{
using (ISession Session = UnitOfWork.NhibernateHelper())
{
return Session.Get<T>(id);
}
}
public T Insert(T entity)
{
try
{
using (ISession Session = UnitOfWork.NhibernateHelper())
{
using (ITransaction Transaction = Session.BeginTransaction())
{
Session.Save(entity);
Transaction.Commit();
}
}
return entity;
}
catch (Exception)
{
throw;
}
}
public void Update(T entity)
{
using (ISession Session = UnitOfWork.NhibernateHelper())
{
using (ITransaction Transaction = Session.BeginTransaction())
{
Session.Update(entity);
Transaction.Commit();
}
}
}
public void Delete(int id)
{
using (ISession Session = UnitOfWork.NhibernateHelper())
{
using (ITransaction Transaction = Session.BeginTransaction())
{
Session.Delete(Session.Load<T>(id));
Transaction.Commit();
}
}
}
}
here is my usersService
public class UsersService : IUsersService
{
private readonly IRepository<Users> _Repository;
#region Constructor
public UsersService(IRepository<Users> Repository)
{
_Repository = Repository;
}
#endregion
#region Service Implementation
public List<Users> GetListAll()
{
return _Repository.GetAll().ToList();
}
public Users GetById(int Id)
{
return _Repository.GetById(Id);
}
public Users Insert(Users user)
{
return _Repository.Insert(user);
}
public void Update(Users user)
{
_Repository.Update(user);
}
public void Delete(int Id)
{
_Repository.Delete(Id);
}
//public int execute()
//{
// return _Repository.execute();
//}
}
so what i need to know is why the Expose_configuration method causes the tables to reset... and secondly ,Am i moving in the right way in this implementation or not.
if you guys have any update of improvements please tell me ..
best regards.
The evil lies in details
You wrote:
... ExposeConfiguration when I removed it all the methods works fine but when i add it, it resets the tables in the database.
And that's pretty much normal way of operations, since if we look up NHiberate's SchemaExport classes Create method signature, it reads:
public void Create(Action<string> scriptAction, bool execute)
It's documentation states that Create():
Run the schema creation script
And about it parameters:
scriptAction - an action that will be called for each line of the generated ddl.
execute - if the ddl should be executed against the Database.
And you call it as:
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true))
Your problem lies in that you pass true to the execute parameter, which will -as stated in documentation- execute the schema creation script, which might include drop and rerecration of existing database objects.
Why create demons?
About your second idea, I really see no benefit of adding another layer of indirection to your code, and that's where you summon unneeded demons.
The NHibernate ORM itself is an abstraction itself, why add one more generic one around it? Your Repository<T> just simply calls the already implemented generic NHibernate methods... sort of acting as Proxy to hide NHibernate, if that's intentional please pardon me, but it looks like it's not.
On a final note: your UsersService class first violates the Single responsibility principle and makes your life harder by maintaining and testing it. Second, this class is also not much more than a proxy to call the repository to return values from.
Let me illustrate the problem:
Client calls UsersService.GetById(Id)
Service calls _Repository.GetById(Id)
Your generic abstraction Repository calls NHibernates Session.Get<T>(id)
Do you see the problem?
How easier it would be to say use a pattern that might help you in this case, that is the Command Query Separation.
Where your commands are responsible for writes, and queries about reads and both suits your use-cases.
You can read about my answers earlier about queries and commands.
I am building an application (a web api to be specific) and I want to implement the repository pattern to abstract the data access layer and prepare it for future changes.
My goal is to make the repositories interfaces abstract enough to be able to implement every technology on top of them, starting from Native SQL Client (running sql command) to orm's like EF or dapper.
I have read some articles about repositories and the interface of my generic repository looks something like that:
interface IRepository<T>
{
IEnumerable<T> FindAll();
IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
T FindById(int id);
void Add(T entity);
void Remove(T entity);
}
I want the method FindBy to accept a linq expression because the other option is making it accept native sql and that won't work too well with technologies like linq to entity of EF.
The problem is that i also want to be able to implement a native sql repository on top of this interface and in order to implement a native sql repository, i need to run sql command, strings.
In this interface i don't accept any sql command as string, i accept linq expressions, and the native sql client can't handle linq expressions (as far as i know).
So my question is, how can i make this interface be compatible with any technology/orm/library/client/adapter, you get the idea...
Thanks,
Arik
Adbstracting repository is a good idea. I'll try to help you.
First of all, your repository must independent of persistance, so you need to remove method FindBy(Expression<Func<T, bool>> predicate), rather replace it with some kind of specification pattern:
interface IRepository<T>
{
IEnumerable<T> FindAll();
IEnumerable<T> FindBy(ISpecification<T> specification);
T FindById(int id);
void Add(T entity);
void Remove(T entity);
}
public interface ISpecification<T>
{
IEnumerable<T> Execute(DbContext context);
}
So, now we have independent repository. And then you can create implementation of specification and repository for linq-supported persistance, it can looks like this:
public class LinqRepository<T> : IRepository<T>
{
private readonly DbContext _context;
public LinqRepository(DbContext context)
{
_context = context;
}
public IEnumerable<T> FindBy(ISpecification<T> specification)
{
return specification.Execute(_context);
}
//and others...
}
public class LinqSpecification<T> : ISpecification<T>
{
private readonly Expression<Func<T, bool>> _predicate;
public LinqSpecification(Expression<Func<T, bool>> predicate)
{
this._predicate = predicate;
}
public IEnumerable<T> Execute(DbContext context)
{
return context.Set<T>().Where(_predicate).ToList();
}
}
And call like this:
IRepository<Person> repository = new LinqRepository<Person>(dbContext);
var adults = repository.FindBy(new LinqSpecification<Person>(p => p.Age > 18));
Another side, when you need to implement non-linq repository, it can look like this:
public class SqlRepository<T> : IRepository<T>
{
private readonly DbContext _context;
public SqlRepository(DbContext context)
{
_context = context;
}
public IEnumerable<T> FindBy(ISpecification<T> specification)
{
return specification.Execute(_context);
}
}
public class SqlSpecification<T> : ISpecification<T>
{
private readonly string _query;
public SqlSpecification(string query)
{
_query = query;
}
public IEnumerable<T> Execute(DbContext context)
{
return context.ExecuteSql<T>(_query);
}
}
And call:
IRepository<Person> repository = new SqlRepository<Person>(dbContext);
var adults = repository.FindBy(new SqlSpecification<Person>("SELECT * FROM Persons WHERE Age > 18"));
Of couse, it's not ideal variant, but it depends on your system architecture and other components. But it can be used as background.
I'm trying to learn some NHibernate after diving into EF4. Is the equivalent of the EF4 ObjectContext (or DbContext) the NHibernate Session?
Specifically, in EF4, you derive from ObjectContext (or DbContext) and your class contains explicit ObjectSet's of each entity, for example:
public class EcommerceContext : ObjectContext {
public ObjectSet<Customer> Customers {get; set;}
public ObjectSet<Product> Products {get; set;}
// etc.
}
In the NHib examples I've seen so far, the Session object isn't used this way. Am I missing something?
If you're using NHibernate 3 it's fairly trivial to implement a data context.
public class YourDataContext
{
public ISession Session { get; private set; }
public YourDataContext(ISession session)
{
Session = session;
}
public IQueryable<Customer> Customers
{
get
{
return Session.Query<Customer>();
}
}
}
The same thing is possible in NHibernate 2 but slightly different. You will need the NHibernate.Linq library which is in the contrib modules.
public class YourDataContext:NHibernateContext
{
public YourDataContext(ISession session)
: base(session){}
public IOrderedQueryable<Customer> Customers
{
get
{
return Session.Linq<Customer>();
}
}
}
I'm guessing since you're asking about a datacontext that you're looking to use Linq, and if that's the case, you should definitely use NH3 as the linq provider is much improved.
It should be noted that a datacontext in EF and a datacontext in NH are going to behave differently because NH does not do objectracking and EF does, among other things. You'll see other differences as you learn about it.
So I really like working with NHibernate but always used Spring.Net with it.
I recently came across StructureMap by Jeremy Miller and really like it better than Spring.Net. On his StructureMap site he promises an example on how to use NHibernate and StructureMap together. Unfortunately he has not had time to do it (or I can't find it).
So does anyone have an example on how to handle the NHibernate Session with StructureMap?
So, I apologize that we did not get the NHibernate with StructureMap example done earlier. Eventually, I would like to publish it in the StructureMap documentation, but I need some feedback first. You can see the full example on my blog:
http://trason.net/journal/2009/10/7/bootstrapping-nhibernate-with-structuremap.html
That being said, I can hit the highlights here. There is an NHibernateRegistry that makes available four things: an NHibernate.Configuration (as a Singleton), an ISessionFactory (as a Singleton), an ISession (scoped Hybrid (HttpContext if available, falling back to Thread local storage)), and a very simple IUnitOfWork. Also, there is an HttpModule to manage the UnitOfWork per web request.
Here is the code for the NHibernateRegistry:
using NHibernate;
using NHibernate.ByteCode.Castle;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernateBootstrap.Core.Domain;
using StructureMap.Attributes;
using StructureMap.Configuration.DSL;
using Environment=NHibernate.Cfg.Environment;
namespace NHibernateBootstrap.Core.Persistence
{
public class NHibernateRegistry : Registry
{
public NHibernateRegistry()
{
var cfg = new Configuration()
.SetProperty(Environment.ReleaseConnections, "on_close")
.SetProperty(Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName)
.SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)
.SetProperty(Environment.ConnectionString, "data source=bootstrap.sqlite;Version=3")
.SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
.AddAssembly(typeof(Blog).Assembly);
var sessionFactory = cfg.BuildSessionFactory();
ForRequestedType<Configuration>().AsSingletons().TheDefault.IsThis(cfg);
ForRequestedType<ISessionFactory>().AsSingletons()
.TheDefault.IsThis(sessionFactory);
ForRequestedType<ISession>().CacheBy(InstanceScope.Hybrid)
.TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
ForRequestedType<IUnitOfWork>().CacheBy(InstanceScope.Hybrid)
.TheDefaultIsConcreteType<UnitOfWork>();
ForRequestedType<IDatabaseBuilder>().TheDefaultIsConcreteType<DatabaseBuilder>();
}
}
}
Here is the code for the Unit of Work:
using System;
using NHibernate;
namespace NHibernateBootstrap.Core.Persistence
{
public interface IUnitOfWork : IDisposable
{
ISession CurrentSession { get; }
void Commit();
}
}
using NHibernate;
namespace NHibernateBootstrap.Core.Persistence
{
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
CurrentSession = _sessionFactory.OpenSession();
_transaction = CurrentSession.BeginTransaction();
}
public ISession CurrentSession { get; private set;}
public void Dispose()
{
CurrentSession.Close();
CurrentSession = null;
}
public void Commit()
{
_transaction.Commit();
}
}
}
Here is the NHibernateModule for web applications:
using System;
using System.Web;
using NHibernateBootstrap.Core.Persistence;
using StructureMap;
namespace NHibernateBootstrap.Web
{
public class NHibernateModule : IHttpModule
{
private IUnitOfWork _unitOfWork;
public void Init(HttpApplication context)
{
context.BeginRequest += ContextBeginRequest;
context.EndRequest += ContextEndRequest;
}
private void ContextBeginRequest(object sender, EventArgs e)
{
_unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>();
}
private void ContextEndRequest(object sender, EventArgs e)
{
Dispose();
}
public void Dispose()
{
_unitOfWork.Dispose();
}
}
}
Does this help: http://devlicio.us/blogs/billy_mccafferty/archive/2007/02/05/inject-di-container-into-domain-objects-with-nhibernate.aspx
Edit here: I posted this comment before wbinford's answer was posted. I still think using NCommon is good, but his answer above is a little cleaner and does not require the use of another third party tool.
I really didn't get the answers I was looking for but I found a nice framework called NCommon. It implements the unit of work pattern along with the repository pattern with NHibernate, LinqToSql or the Entity Framework. It also handled the NHibernate ISession as well as configuration for NHibernate. I used the tool with StructureMap and NHibernate. I did have to get the service adapter for StructureMap, but once set up it works rather nicely.
I'm fairly new to NHibernate and have run into a strange inheritance chaining issue with my repository classes. I've been using Gabriel Schenker's FAQ as a reference, and following his examples I've been creating interfaces to define contracts for DAO operations in "repository" classes. The data schema I'm working with is rather extensive, and after a little while I found myself duplicating a lot of code. Specifically, the Add, Update, Delete, and "GetByID" methods were exactly the same after I added a generic "EntityType" parameter to the base interface. So, for example, this would be the most basic interface for repository operations:
public interface IBasicRepository<EntityType> where EntityType : class
{
void Add(EntityType entity);
void Remove(EntityType entity);
void Update(EntityType entity);
EntityType GetByID<IDType>(IDType id);
}
I'll just talk about the Add method from now on, for the sake of brevity. With the generic EntityType, the implementations were all the same:
public void Add(EntityType entity)
{
using (ISession session = NHUtility.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(entity);
transaction.Commit();
}
}
}
Obviously, typing this same method body repeatedly (with the slight change of type) isn't only annoying, it's bad design in my book. So I created an abstract base class I'll call RepositoryBase which provides the implementation for Add(). Since I'm using an abstract instead of an interface, I "break the interface chain" for classes inheriting from RepositoryBase and am forced to make any derivation abstract as well, even though it seems more "correct" to use an interface. Using this crappy little entity example....
public class Entity1
{
public Guid ID { get; set; }
public String Name { get; set; }
}
...one can't do this...
public interface IEntity1Repository : RepositoryBase<Entity1>
{
//Illegal!!!! Bad, naughty programmer!
}
...but this is fine....
public abstract class Entity1RepositoryBase : RepositoryBase<Entity1>
{
public abstract ICollection<Entity1> GetByName(string name);
}
This just bothers me. It works, but it rubs me the wrong way, especially as the chain of inheritance/implementation with this particular schema could go quite deep. So I guess my questions are:
Am I just being stupid and anal retentive about this?
Is there a different/better design that I should be looking at here? I've looked at some other examples (notably Billy McCafferty's) and Schenker's approach seems simplest for novice NHibernating.
Thanks in advance.
One option could be:
public interface IRepository<T> where T: class
{
void Add(T entity);
void Remove(T entity);
void Update(T entity);
T GetByID<IDType>(IDType id);
}
With a base class that implements that interface. Ie:
public abstract class RepositoryBase<T> : IRepository<T> where T: class
{
...
}
Which is then extended for each type of entity if necessary:
public interface IProductRepository : IRepository<Product>
{
// Add extra methods
}
public class ProductRepository : RepositoryBase<Product>, IProductRepository
{
// Implement extra methods
}