Here is what I do:
1. Define entities (some code skipped for clarity):
[DataServiceKey("CategoryID")]
public class Categories
{
public virtual int CategoryID { get; set; }
public virtual ICollection<Products> Products { get; set; }
/**/
}
public class CategoriesMap : ClassMap<Categories>
{
public CategoriesMap()
{
Id(x => x.CategoryID).GeneratedBy.Increment();
HasMany(x => x.Products)
.Table("Products")
.KeyColumn("CategoryID");
/**/
}
}
[DataServiceKey("ProductID")]
public class Products
{
public virtual int ProductID { get; set; }
public virtual int CategoryID { get; set; }
public virtual Categories Category { get; set; }
/**/
}
public class ProductsMap : ClassMap<Products>
{
public ProductsMap()
{
Id(x => x.ProductID);
Map(x => x.CategoryID);
References(x => x.Category).Not.LazyLoad()
.Column("CategoryID");
/**/
}
}
2. Define context
public class NorthwindContext : NHibernateDataContext
{
public NorthwindContext(ISession session) : base(session) { }
public IQueryable<Categories> Categories
{
get { return new NhQueryable<Categories>(
base.Session.As<ISessionImplementor>()); }
}
public IQueryable<Products> Products
{
get { return new NhQueryable<Products>(
base.Session.As<ISessionImplementor>()); }
}
/**/
public static ISessionFactory CreateSessionFactory(string connectionString)
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(connectionString)
.Cache(c => c
.UseQueryCache()
.ProviderClass<HashtableCacheProvider>())
.ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<NorthwindContext>())
.BuildSessionFactory();
}
}
So far so good. All tests work.
3. Now I implement an OData service:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class NHibernateMsSql : DataService<NorthwindContext>, IDisposable
{
private ISession session;
public void Dispose()
{
if (this.session != null)
{
this.session.Dispose();
this.session = null;
}
}
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.AcceptCountRequests = true;
config.DataServiceBehavior.AcceptProjectionRequests = true;
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.UseVerboseErrors = true;
}
protected override void HandleException(HandleExceptionArgs args)
{
base.HandleException(args);
Elmah.ErrorLog.GetDefault(null).Log(new Error(args.Exception));
}
protected override NorthwindContext CreateDataSource()
{
var factory = NorthwindContext.CreateSessionFactory(
ConfigurationManager.ConnectionStrings["NorthwindContext.NH.MsSql"].ConnectionString);
this.session = factory.OpenSession();
this.session.FlushMode = FlushMode.Auto;
return new NorthwindContext(this.session);
}
Then it works fine for non-projection queries but fails as soon as I call SelectMany on it.
Vagif