I am new to using Fluent NHibernate and NHibernate for the first time. I've used a custom written mapper since about 2000 that was written in house. Made a switch to LinqToSQL about 2 years ago, and about 6 months ago to Entities.
I'd like to see what Fluent/NHibernate have to offer. However, I can't seem to get it to run correctly. The following is a copy of my classes, their references, the ClassMaps. Can someone tell me if this simple implementation is correct?
This is my mappings and object classes:
using System;
using FluentNHibernate.Mapping;
namespace MyData.Data.Mappings
{
public class Login
{
public virtual int LoginId { get; private set; }
public virtual string Username { get; set; }
public virtual User User { get; set; }
}
public class LoginClassMap : ClassMap<Login>
{
public LoginClassMap()
{
Table("Logins");
Id(d => d.LoginId).GeneratedBy.Guid();
Map(d => d.Username).Not.Nullable().Length(50);
HasOne(d => d.User).ForeignKey("UserId").Cascade.All();
}
}
public class User
{
public virtual Guid UserId{ get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual Login Login { get; set; }
}
public class UserClassMap : ClassMap<User>
{
public UserClassMap()
{
Table("Users");
Id(d => d.UserId).GeneratedBy.Guid();
Map(d => d.FirstName).Not.Nullable().Length(100);
Map(d => d.LastName).Not.Nullable().Length(100);
References(r => r.Login, "UserId").Not.Nullable();
}
}
}
This is my Repository:
using System;
using System.Linq;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate.Linq;
using MyData.Data.Mappings;
namespace MyData.Data.Repository
{
public class LoginRepository
{
private readonly ISessionFactory _sessionFactory;
ISession _session;
public LoginRepository()
{
_sessionFactory = this.CreateSessionFactory();
_session = _sessionFactory.OpenSession();
}
private ISessionFactory CreateSessionFactory()
{
string connString = "MyDataConnectionString";
FluentConfiguration config = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(
x => x.FromConnectionStringWithKey(connString)))
.ExposeConfiguration(
c => c.SetProperty("current_session_context_class", "webContext"))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Login>());
return config.BuildSessionFactory();
}
public IQueryable<Login> GetAllLogins()
{
return _session.Linq<Login>();
}
}
}
Whenever it gets to config.BuildSessionFactory() it throws the following error:
An invalid or incomplete configuration was used while creating a SessionFactory.
The inner Exception is:
Exception has been thrown by the target of an invocation.
Is this the correct way to approach this? Any ideas or tweaks would be greatly appreciated!
Sean, you cannot use GeneratedBy.Guid() on LoginId because it's an int. Try to use another generator or change the type of LoginId.
I suspect you cannot use "private set" on UserId because it's the Id.
Also, HasOne(d => d.User).ForeignKey("UserId") means that if you expose your database model from your mappings, the name of the FK constraint will be "UserId". It seems to me that your intention was to specify the name column that holds the PK on table "Users".
These links have more infos:
http://wiki.fluentnhibernate.org/Fluent_mapping
http://jagregory.com/writings/i-think-you-mean-a-many-to-one-sir/
one-to-one fluent nhibernate?
It seems you forgot to specify proxy factory. It can be done like this: