Reputation: 111
I'm new to using NHibernate and I struggled to find clear examples online of how to create a ClassMap for a stored procedure without using XML for the mappings. I recently got this working using the Fluent interfaces and wanted to share what I've learned.
The stored procedure in question returns an object like this:
public class ProductCategoryNavigation
{
public virtual int CategoryId { get; protected set; }
public virtual int CategoryNodeId { get; set; }
public virtual int ParentCategoryNodeId { get; set; }
public virtual string Name { get; set; }
public virtual string Title { get; set; }
public virtual string SeoUrl { get; set; }
public virtual bool IsActive { get; set; }
public virtual int DisplayOrder { get; set; }
public virtual int ProductCount { get; set; }
}
So, how do I create a ClassMap that NHibernate will use to map the result of a stored procedure to this object?
Upvotes: 3
Views: 6347
Reputation: 4946
Assuming you have NHibernate properly installed, you would create a new class where ever your are storing your class maps.
Create a class like:
public class PcnMap : ClassMap<ProductCategoryNavigation>
{
Table("TableName");
Id( x => x.CategoryId );
Map( model => model.CategoryNodeId );
// more like this for all your properties
}
Once you have that set up, you use your repositories as needed.
Keep in mind that is only a basic set up. The more complicated your database structure is, the more complicated your class map will get.
Upvotes: 0
Reputation: 111
The ClassMap looks like this:
public sealed class ProductCategoryNavigationMap : ClassMap<ProductCategoryNavigation>
{
public ProductCategoryNavigationMap()
{
ReadOnly();
// Set "CategoryId" property as the ID column. Without this,
// OpenSession() threw an exception that the configuration was invalid
Id(x => x.CategoryId);
Map(x => x.CategoryNodeId);
Map(x => x.ParentCategoryNodeId);
Map(x => x.Name);
Map(x => x.Title);
Map(x => x.SeoUrl);
// The column name returned from the sproc is "VisibleInd",
// so this is here to map it to the "IsActive" property
Map(x => x.IsActive).Column("VisibleInd");
Map(x => x.DisplayOrder);
Map(x => x.ProductCount);
}
}
The call to the stored procedure looks like this:
public List<NavigationViewModel> GetNavigationViewModel(int portalId, int localeId)
{
const string sql = "EXEC [dbo].[Stored_Procedure_Name] @PortalId=:PortalId, @LocaleId=:LocaleId";
return _session.CreateSQLQuery(sql)
.AddEntity(typeof(ProductCategoryNavigation))
.SetInt32("PortalId", portalId)
.SetInt32("LocaleId", localeId)
.List<ProductCategoryNavigation>()
.Select(x => new NavigationViewModel
{
CategoryId = x.CategoryId,
CategoryNodeId = x.CategoryNodeId,
ParentCategoryNodeId = x.ParentCategoryNodeId,
Name = x.Name,
Title = x.Title,
SeoUrl = x.SeoUrl,
IsActive = x.IsActive,
DisplayOrder = x.DisplayOrder,
ProductCount = x.ProductCount
})
.ToList();
}
The AddEntity calls says what Entity class to map the results to, which will use the ProductCategoryNavigationMap defined above:
.AddEntity(typeof(ProductCategoryNavigation))
If you look carefully at the value of the "sql" variable, you'll see two parameters:
Those are set by making calls to:
.SetInt32("PortalId", portalId)
.SetInt32("LocaleId", localeId)
Then the call to .List<ProductCategoryNavigation>()
provides us with an IList, which allows us to use LINQ to project whatever we want. In this case I'm getting a List of NavigationViewModel, which is currently the same as ProductCategoryNavigation but can change independently of the entity as needed.
I hope this helps other developers new to NHibernate!
Upvotes: 8