How to represent next nhibernate xml in fluent-nhibernate?
<set name="Items" lazy="true" table="CATEGORY_ITEMS">
<key column="CATEGORY_ID"/>
<composite-element class="CategorizedItem">
<parent name="Category"/>
<many-to-one name="Item"
class="Item"
column="ITEM_ID"
not-null="true"/>
<property name="Username" column="USERNAME" not-null="true"/>
<property name="DateAdded" column="DATE_ADDED" not-null="true"/>
</composite-element>
</set>
HasMany(x => x.Items)
.Table("CATEGORY_ITEMS")
.Component(com =>
{
com.ParentReference(x => x.Category);
com.References(x => x.Item)
.Not.Nullable();
com.Map(x => x.Username)
.Not.Nullable();
com.Map(x => x.DateAdded)
.Not.Nullable();
});
I encourage you to look into conventions for specifying the repetitious parts of your mappings, like the uppercase column and table names.
Related
I'm moving from xml mapping to a code based mapping. There is a problem I'm experiencing with NHibernate Map collection.
Below is the xml mapping which perfectly works (it is a bit simplified, there is actually more properties and collections):
<class name="Company" where="IsDeleted=0" lazy="false">
<id name="Id">
<generator class="guid"></generator>
</id>
<map name="Contacts" lazy="true" cascade="all" where="IsDeleted=0">
<key column="CompanyId"></key>
<index column="Id" type="guid"></index>
<one-to-many class="CompanyContact"/>
</map>
</class>
The alternate code mapping I came up with is next:
public CompanyMap()
{
Id(x => x.Id, mapper => mapper.Generator(Generators.Guid));
Map(x => x.Contacts,
m =>
{
m.Where(FILTER);
m.Cascade(Cascade.All);
m.Lazy(CollectionLazy.Lazy);
m.Key(c => c.Column("CompanyId"));
}, k =>
{
k.Element(e =>
{
e.Column("Id");
});
k.OneToMany(e => e.Class(typeof(CompanyContact)));
});
}
The above generates next hbml for map:
<map name="Contacts" lazy="true" cascade="all" where="IsDeleted=0">
<key column="CompanyId" />
<map-key type="Guid" />
<one-to-many class="CompanyContact" />
</map>
I'm obviously lacking index column here. Therefore when generating SQL nhibernate will use the DefaultIndexColumnName which is idx.
So the question is how would I set the index for map?
Update:
According to hibernate documentation I should be using map-key.
So to rephrase the question, how would I set the column property of map-key?
This is not yet implemented for NHibernate version 3.3.1.
Created an issue in Jira for that.
i want to convert this mapping file from NHibernate to Fluent NHibernate
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="CustomCollectionsBasic.Core.Category, CustomCollectionsBasic.Core" table="Categories">
<id name="ID" column="CategoryID" unsaved-value="0">
<generator class="identity" />
</id>
<property name="Name" column="CategoryName" />
<bag name="ProductsInCategory" table="Products" cascade="all" inverse="true"
collection-type="CustomCollectionsBasic.Data.Collections.PersistentProductsType, CustomCollectionsBasic.Data">
<key column="CategoryID" />
<one-to-many class="CustomCollectionsBasic.Core.Product,ustomCollectionsBasic.Core" />
</bag>
</class>
</hibernate-mapping>
I try to convert it by NHibernateHbmToFluent and the result is
public class CategoryMap: ClassMap<CustomCollectionsBasic.Core.Category>
{
public CategoryMap()
{
Table("Categories");
Id(x => x.ID)
.GeneratedBy.
.UnsavedValue(0);
Map(x => x.Name, "CategoryName");
HasMany<CustomCollectionsBasic.Core.Product>(x => x.ProductsInCategory)
.AsBag()
.KeyColumn("CategoryID")
.Table("Products")
.Inverse()
.Cascade;
}
}
but it not working.
Any ideas on how to map this?
Thanks in advance.
Id(x => x.ID)
.GeneratedBy
.Identity()
.UnsavedValue(0);
I think the other stuff is OK
What is fuentHibernate? Why is it used? What is the difference between Hibernate and Fluent Hibernate?
Fluent NHibernate offers an alternative to NHibernate's standard XML mapping files. Rather than writing XML documents (.hbm.xml files), Fluent NHibernate lets you write mappings in strongly typed C# code. This allows for easy refactoring, improved readability and more concise code.
Traditional HBM XML mapping
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="QuickStart" assembly="QuickStart">
<class name="Cat" table="Cat">
<id name="Id">
<generator class="identity" />
</id>
<property name="Name">
<column name="Name" length="16" not-null="true" />
</property>
<property name="Sex" />
<many-to-one name="Mate" />
<bag name="Kittens">
<key column="mother_id" />
<one-to-many class="Cat" />
</bag>
</class>
</hibernate-mapping>
Fluent NHibernate equivalent
public class CatMap : ClassMap<Cat>
{
public CatMap()
{
Id(x => x.Id);
Map(x => x.Name)
.Length(16)
.Not.Nullable();
Map(x => x.Sex);
References(x => x.Mate);
HasMany(x => x.Kittens);
}
}
How do we express this in FNH?
<class name="Order" .... >
....
<set name="PurchasedItems" table="purchase_items" lazy="true">
<key column="order_id">
<composite-element class="Purchase">
<property name="PurchaseDate"/>
<property name="Price"/>
<property name="Quantity"/>
<many-to-one name="Item" class="Item"/> <!-- class attribute is optional -->
</composite-element>
</set>
This should do it:
HasMany(x => x.PurchasedItems)
.Component(c =>
{
c.Map(x => x.PurchaseDate);
c.Map(x => x.Price);
c.Map(x => x.Quantity);
c.References(x => x.Item);
});
i have these 2 classes:
public class Category
{
IDictionary<string, CategoryResorce> _resources;
}
public class CategoryResource
{
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
and this is xml mapping
<class name="Category" table="Categories">
<id name="ID">
<generator class="identity"/>
</id>
<map name="Resources" table="CategoriesResources" lazy="false">
<key column="EntityID" />
<index column="LangCode" type="string"/>
<composite-element class="Aca3.Models.Resources.CategoryResource">
<property name="Name" column="Name" />
<property name="Description" column="Description"/>
</composite-element>
</map>
</class>
and i'd like to write it with Fluent.
I found something similar and i was trying with this code:
HasMany(x => x.Resources)
.AsMap<string>("LangCode")
.AsIndexedCollection<string>("LangCode", c => c.GetIndexMapping())
.Cascade.All()
.KeyColumn("EntityID");
but i dont know how to map the CategoryResource entity as a composite element inside the Category element.
Any advice ?
thanks
I think the mapping you're looking for is something like this:
HasMany<CategoryResource>(x => x._resources)
.AsMap<string>("LangCode")
.KeyColumn("EntityID")
.Table("CategoryResources")
.Component(x =>
{
x.Map(c => c.Name);
x.Map(c => c.Description);
})
.Cascade.All();