流畅的 nhibernate 自动映射推断出错误的键

发布于 2024-09-16 16:33:06 字数 1301 浏览 5 评论 0原文

在使用 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>();

希望这有意义。感谢您的任何想法。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

圈圈圆圆圈圈 2024-09-23 16:33:08

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

流畅的 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
}

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
}
抠脚大汉 2024-09-23 16:33:08

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

感谢

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文