text: (Portuguese only, sorry!)
  Conhecem o meu blog em português?
  This:
  When using NHibernate’s loquacious configuration, you have the change to tell NHibernate what to do with the mappings if the database schema that you are targeting does not exist or does not match the current mappings, when a session factory is created. Like this:
  1: Configuration cfg = new Configuration()
  2: .DataBaseIntegration(db =>
  3: {
  4: db.BatchSize = 20;
  5: db.ConnectionStringName = connectionStringName;
  6: db.Dialect<MsSql2008Dialect>();
  7: db.Driver<Sql2008ClientDriver>();
  8: db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
  9: db.IsolationLevel = IsolationLevel.ReadCommitted;
  10: db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
  11: db.LogFormattedSql = true;
  12: db.LogSqlInConsole = false;
  13: db.OrderInserts = true;
  14: db.PrepareCommands = true;
  15: db.SchemaAction = SchemaAutoAction.Validate;
  16: })
  This value is the same as the property hbm2ddl.auto, that you can set either programmatically:
  1: cfg.SetProperty(NHibernate.Cfg.Environment.Hbm2ddlAuto, (createSchema == true) ? SchemaAutoAction.Update.ToString() : SchemaAutoAction.Validate.ToString());
  or through XML configuration:
  1: <hibernate-configuration
  2: <session-factory>
  3: <property name="hbm2ddl.auto">Update</property>
  The value you assign to SchemaAction is very important, because it can cause your database to be dropped and created again, losing all data in it!
  The possible values are:
  Recreate (drop-create): unconditionally drops and creates all of the tables for all of the mapped entities; when the session factory is disposed, drop them again;
  Create (create): unconditionally drops and creates all of the tables for all of the mapped entities;
  Update (update): check every table against the mappings, and, if there are changes, use DDL commands to update the tables so that they match the schema;
  Validate (validate): check the existing tables against the mappings and throw an exception if there are differences.
  So, it should be clear that you would only use Create or Recreate for demonstration purposes, self contained unit tests or fresh installations, not real-life scenarios.
  Some additional notes:
  When you use manually assigned identifiers, you are responsible for assigning a valid id to your entity. By valid, I mean, some key that doesn’t already exist on the database.
  Because it’s not NHibernate who is managing it, when time comes for the entity to be saved, NHibernate needs to issue a SELECT statement in order to find out if a row with the given id exists, in which case an UPDATE statement will be issued, otherwise, it will be an INSERT. So, you have to be very careful not no overwrite an existing row unintentionally.
  Generally speaking, there’s no need to use manually assigned identifiers, and you should avoid them.
  A list of all my posts on NHibernate extensibility:
  Here you will find a list of all my posts on ASP.NET Web Forms extensibility.
  If you have any questions, comments or suggestions, do let me know!
  This is not really an NHibernate-specific problem, but, since a lot of people are having trouble, I decided to mention it.
  Sets are probably the most used of all collection types in NHibernate. Up to .NET 4, there was no set implementation in the BCL, so NHibernate historically used Iesi Collections. The set specification says that it doesn’t allow repeated entries, but there are many ways to implement this, and one of the most used ones is Iesi.Collections.Generic.HashedSet<T>, which is also used internally (and automatically) by NHibernate in its NHibernate.Collection.Generic.PersistentGenericSet<T>. Now, this class relies on the hash code of its items and allocates them on an internal structure, where it is assumed that this hash code will never change, which is also consistent with Microsoft’s guidelines. You can see a good description on Eric Lippert’s blog: Guidelines and rules for GetHashCode.
  So, what is the problem? The problem is, if changes on your entity cause its hash code to change, the set implementation won’t be able to find the object where it was supposed to be, so it won’t be possible to remove the object from the collection.
  Consider this code that illustrates the problem (just for demonstration purposes, of course):
  1: class Test
  2: {
  3: public Int32 Id
  4: {
  5: get;
  6: set;
  7: }
  8:
  9: private Int32 hashCode = 1;
  10:
  11: public override Int32 GetHashCode()
  12: {
  13: this.hashCode *= -1;
  14:
  15: return (this.hashCode);
  16: }
  17: }
  And some typical usage:
  1: Iesi.Collections.Generic.ISet<Test> col = new Iesi.Collections.Generic.HashedSet<Test>();
  2: col.Add(new Test() { Id = 1 });
  3: col.Add(new Test() { Id = 2 });
  4:
  5: Test t = col.Last();
  6: Boolean contains = col.Contains(t);
  7: Boolean removed = col.Remove(t);
  As you can see for yourself, the Contains and the Remove method may return false, and it will be impossible to remove the item, even though it is there.
  There are two ways to go around this:
  One example of a GetHashCode implementation that never changes could be:
  1: public Int32 Id { get; set; }
  2: public String Name { get; set; }
  3:
  4: private Int32 hashCode = 0;
  5:
  6: public override Int32 GetHashCode()
  7: {
  8: if (this.hashCode != 0)
  9: {
  10: return(this.hashCode);
  11: }
  12:
  13: this.hashCode = (result * 397) ^ this.Id.GetHashCode();
  14: this.hashCode = (result * 397) ^ (this.Name ?? String.Empty).GetHashCode();
  15:
  16: return (this.hashCode);
  As a side note, NHibernate 4.0 will be out in some months, will target .NET 4 and so will make use of the set collections that now exist inside the BCL, namely System.Collections.Generic.ISet<T> and System.Collections.Generic.HashSet<T>, and Iesi Collections 4 have been refactored to use them. The problem, however, remains exactly the same.
  A.
  A long time ago I submitted a request to the ASP.NET team for having the standard DropDownList support HTML’s optgroup tag:. For those of you not familiar with this tag – that has been around for quite some time, by the way –, it allows for something like this:
  In a nutshell, we can have grouped list items. The issue is still open, but, since it is such a handy feature, and one that I need quite often, I decided to implement support for it on top of the existing DropDownList. Again, my solution uses tag mapping, which you should know from my previous posts, so I can add support for it on all of the already declared DropDownLists.
  I wanted to support the two basic scenarios:
  I started by implementing a control that inherits from DropDownList:
  1: public class GroupedDropDownList : DropDownList
  3: public String DataGroupField
  9: protected override void PerformDataBinding(IEnumerable dataSource)
  10: {
  11: base.PerformDataBinding(dataSource);
  13: if ((String.IsNullOrWhiteSpace(this.DataGroupField) == false) && (dataSource != null))
  14: {
  15: ListItemCollection items = this.Items;
  16: IEnumerable<Object> data = dataSource.OfType<Object>();
  17: Int32 count = data.Count();
  18:
  19: for (Int32 i = 0; i < count; ++i)
  20: {
  21: String group = DataBinder.Eval(data.ElementAt(i), this.DataGroupField) as String ?? String.Empty;
  22:
  23: if (String.IsNullOrWhiteSpace(group) == false)
  24: {
  25: items[i].Attributes["Group"] = group;
  26: }
  27: }
  28: }
  29: }
  30:
  31: protected override void RenderContents(HtmlTextWriter writer)
  32: {
  33: ListItemCollection items = this.Items;
  34: Int32 count = items.Count;
  35: var groupedItems = items.OfType<ListItem>().GroupBy(x => x.Attributes["Group"] ?? String.Empty).Select(x => new { Group = x.Key, Items = x.ToList() });
  36:
  37: if (count > 0)
  38: {
  39: Boolean flag = false;
  40:
  41: foreach (var groupedItem in groupedItems)
  42: {
  43: if (String.IsNullOrWhiteSpace(groupedItem.Group) == false)
  44: {
  45: writer.WriteBeginTag("optgroup");
  46: writer.WriteAttribute("label", groupedItem.Group);
  47: writer.Write('>');
  48: }
  49:
  50: for (Int32 i = 0; i < groupedItem.Items.Count; ++i)
  51: {
  52: ListItem item = groupedItem.Items[i];
  53:
  54: if (item.Enabled == true)
  55: {
  56: writer.WriteBeginTag("option");
  57:
  58: if (item.Selected == true)
  59: {
  60: if (flag == true)
  61: {
  62: this.VerifyMultiSelect();
  63: }
  64:
  65: flag = true;
  66:
  67: writer.WriteAttribute("selected", "selected");
  68: }
  69:
  70: writer.WriteAttribute("value", item.Value, true);
  71:
  72: if (item.Attributes.Count != 0)
  73: {
  74: item.Attributes.Render(writer);
  75: }
  76:
  77: if (this.Page != null)
  78: {
  79: this.Page.ClientScript.RegisterForEventValidation(this.UniqueID, item.Value);
  80: }
  81:
  82: writer.Write('>');
  83: HttpUtility.HtmlEncode(item.Text, writer);
  84: writer.WriteEndTag("option");
  85: writer.WriteLine();
  86: }
  87: }
  88:
  89: if (String.IsNullOrWhiteSpace(groupedItem.Group) == false)
  90: {
  91: writer.WriteEndTag("optgroup");
  92: }
  93: }
  94: }
  95: }
  96: }
  In case you are wondering, the implementation of RenderContents comes from the standard ListControl, here:. As you can see, I overrode two methods and added an extra property:
  The new DataGroupField property, similar to DataTextField and DataValueField, if specified, will contain the name of the property in the data source that holds each item’s group name, when using data binding. If not specified, no grouping will occur. Do note that this only applies to data binding, not manually added ListItems.
  Now, for using this control, we can either use it explicitly:
  1: <My:GroupedDropDownList
  2: <asp:ListItem
  3: <asp:ListItem
  4: <asp:ListItem
  5: <asp:ListItem
  6: <asp:ListItem
  7: </My:GroupedDropDownList>
  Or use a tag mapping:
  1: <tagMapping>
  2: <add tagType="System.Web.UI.WebControls.DropDownList" mappedTagType="MyNamespace.GroupedDropDownList, MyAssembly"/>
  3: </tagMapping>
  In which case, you keep the standard DropDownList declaration but add the Group attribute to the ListItems, which works because ListItem implements IAttributeAccessor:
  1: <asp:DropDownList
  7: </asp:DropDownList>
  And if you prefer to use data binding, you add an extra attribute for the DataGroupField property (DropDownList also implements IAttributeAccessor):
  1: <asp:DropDownList
  And on code behind (or a data source control):
  1: protected void OnLoad(EventArgs e)
  3: var items = new List<Object>();
  4: items.Add(new { Text = "CSS", Group = "Web" });
  5: items.Add(new { Text = "HTML", Group = "Web" });
  6: items.Add(new { Text = "JavaScript", Group = "Web" });
  7: items.Add(new { Text = "WPF", Group = "Windows" });
  8: items.Add(new { Text = "Windows Forms", Group = "Windows" });
  9:
  10: this.list.DataSource = items;
  11: this.list.DataBind();
  13: base.OnLoad(e);
  14: }
  And you will get all items nicely grouped!
  As you can see, tag mapping is very powerful, and, if used with controls that support extensibility, can be very useful. Hope this helps!