流利的nhibernate自动推断不正确的密钥

时间:2010-08-30 12:21:17

标签: nhibernate fluent-nhibernate

在使用Fluent NHibernate进行自动化时,我无法使用CreateCriteria向条件查询添加外部联接。

以下是我的实体 -

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; }
    }

我尝试使用以下内容将外部联接添加到我的条件查询 -

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

但是我收到了错误 -

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

所以它似乎试图自动设置第二个表的id,但不知道将它设置为什么。有没有办法可以专门设置ID?这是我的会议 -

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>();

希望这有点道理。谢谢你的任何想法。

2 个答案:

答案 0 :(得分:1)

您似乎已经回答了自己的问题,所以我只是要提出一些建议......

关于流畅的nhibernate的一个好处是它遵循自动创建映射的约定。您的实体似乎与数据库表的名称非常相关。

为了映射到不同的数据库约定,同时保留实体和列的理想名称,您可以使用一些自定义约定:

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是一个知道如何缩写表名的类。

这些将来自:

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

表格如下:

CREATE TABLE tbl_table1 {
    tbl1_id INT PRIMARY KEY
    tbl1_date_filed datetime
}

答案 1 :(得分:0)

我在第一个表的覆盖中添加了一个HasMany选项来定义与第二个表的关系。然后我为我的第二个表添加了一个覆盖,它定义了该表的id列。

感谢