views:

16

answers:

2

Hello, I am having trouble using CreateCriteria to add an outer join to a criteria query while using Fluent NHibernate with automapping.

Here are my entities -

public class Table1 : Entity
    {
        virtual public int tb1_id { get; set; }
        virtual public DateTime tb1_date_filed { get; set; }
    .
    .
    .
        virtual public IList<Table2> table2 { get; set; }
    }

public class Table2: Entity
    {
        public virtual int tb2_id { get; set; }
        public virtual int tb2_seqno { get; set; }
        .
        .
        .
        public virtual Table2 table2 { get; set; }
    }

I try to use the following to add an outer join to my criteria query -

CreateCriteria("Table2", NHibernate.SqlCommand.JoinType.LeftOuterJoin);

But I am getting an error -

{"EIX000: (-217) Column (tbl1_id) not found in any table in the query (or SLV is undefined)."}

So it seems that it is trying to automatically set the id of the second table, but doesn't know what to set it to. Is there a way that I can specifically set the id? Here is my Session -

var persistenceModel = AutoMap.AssemblyOf<Table1>()
                .Override<Table1>(c => {    
                    c.Table("case");
                    c.Id(x => x.id).Column("tbl1_id");
                })
                .Where(t => t.Namespace == "MyProject.Data.Entities")
                .IgnoreBase<Entity>();

Hope that makes some sense. Thanks for any thoughts.

A: 

I added a HasMany option to the override for my first table to define the relationship to my second table. I then added an override for my second table which defines the id column for that table.

Thank

czuroski
+1  A: 

You seem to have answered your own question so I'm just going to spout some recommendations...

One of the nice things about fluent nhibernate is that it follows conventions to automatically create mappings. Your entities seem to be very coupled to the names of your database tables.

In order to map to a different database convention while keeping idealistic names for entities and columns you can use some custom conventions:

public class CrazyLongBeardedDBATableNamingConvention
    : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.Table("tbl_" + instance.EntityType.Name.ToLower());
    }
}

public class CrazyLongBeardedDBAPrimaryKeyNamingConvention
    : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        string tableShort = TableNameAbbreviator.Abbreviate(instance.EntityType.Name); 
        instance.Column(tableShort + "_id");
    }
}

class CrazyLongBeardedDBAColumnNamingConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        string name = Regex.Replace(
            instance.Name,
            "([A-Z])",
            "_$1").ToLower();

        var tableShort = TableNameAbbreviator.Abbreviate(instance.EntityType.Name); 
        instance.Column(tableShort + name);
    }
}

TableNameAbbreviator is a class that would know how to abbreviate your table names.

These would map from:

public class Table1 : Entity
{
    virtual public int Id { get; set; }
    virtual public DateTime DateFiled { get; set; }
}

To a table like:

CREATE TABLE tbl_table1 {
    tbl1_id INT PRIMARY KEY
    tbl1_date_filed datetime
}
joshperry