Nhibernate - 如何使用 CompositeId 设计域对象和映射

Posted

技术标签:

【中文标题】Nhibernate - 如何使用 CompositeId 设计域对象和映射【英文标题】:Nhibernate - How to Design DomainObjects and Mappings with CompositeId 【发布时间】:2010-08-18 07:44:34 【问题描述】:

起初我对 ORM、nhibernate 和 FHN 真的很陌生。我现在研究了几天。 我有一个包含 4 个表的现有数据库:

所以我首先尝试让 Auswahl 和 RefAuswahlFilter 工作。

这是我的 DomainObjects:请告诉我什么时候可以做得更好

[Serializable]
public class Auswahl

    public Auswahl()
    
        this.RefFilters = new List<RefAuswahlFilter>();
    

    public virtual IList<RefAuswahlFilter> RefFilters  get; set; 

    //...rest of the Properties

[Serializable]
public class RefAuswahlFilter

    public virtual Auswahl Auswahl  get; set; 
    public virtual long Filterrank  get; set; 
    public virtual string Filter  get; set; 

这是我的映射:

public class AuswahlMap : ClassMap<Auswahl>

    public AuswahlMap()
    
        Table("AUSWAHL");

        Id(x => x.Id)
            .GeneratedBy.Sequence("SEQ_AUSWAHL");

        Map(x => x.Programm);
        Map(x => x.Variante);
        Map(x => x.Returnkey);
        Map(x => x.Beschreibung);

        HasMany<RefAuswahlFilter>(x => x.RefFilters);

    


public class RefAuswahlFilterMap : ClassMap<RefAuswahlFilter>

    public RefAuswahlFilterMap()
    
        Table("REFAUSWAHLFILTER");

        CompositeId()
            .KeyReference(x => x.Auswahl,"IDAUSWAHL")
            .KeyProperty(x => x.Filterrank,"FILTERANK");

        Map(x => x.Filter);
    

如果我运行我的应用程序,我会得到一个包含所有 Auswahl 行的列表。

var l = session.CreateCriteria(typeof(Auswahl)).List<Auswahl>();

但是当我查看一个项目以获取 RefFilters 时,调试器显示以下错误:

innerException "ORA-00904: \"REFFILTERS0\".\"AUSWAHL_ID\": ungültiger Bezeichner\n"

无法初始化集合:[ORMTest.DomainModel.Auswahl.RefFilters#1097][SQL: SELECT reffilters0_.Auswahl_id as Auswahl4_1_, reffilters0_.IDAUSWAHL 作为 IDAUSWAHL1_, reffilters0_.FILTERANK 作为 FILTERANK1_, reffilters0_.IDAUSWAHL 作为 IDAUSWAHL3_0_, FILTERANK as FILTERANK3_0_, reffilters0_.Filter as Filter3_0_ FROM REFAUSWAHLFILTER reffilters0_ WHERE reffilters0_.Auswahl_id=?]

所以我认为我的映射有问题,但我真的不明白。

谢谢。

【问题讨论】:

尝试从 HasMany 中删除 。 HasMany(x => x.RefFilters);不确定该语法是否仍然有效。 【参考方案1】:

我是部分成功的。现在可以从数据库读取。

public AuswahlMap()
    
        Table("AUSWAHL");

        Id(x => x.Id,"ID")
            .GeneratedBy.Sequence("SEQ_AUSWAHL");

        Map(x => x.Programm);
        Map(x => x.Variante);
        Map(x => x.Returnkey).Not.Nullable();
        Map(x => x.Beschreibung);

        HasMany(x => x.RefFilters)
            .Inverse()
            .Cascade.All();    
    

public RefAuswahlFilterMap()
    
        Table("REFAUSWAHLFILTER");

        CompositeId()
            .KeyReference(x => x.Auswahl,"IDAUSWAHL")
            .KeyProperty(x => x.Filterrank);

        Map(x => x.Filter);

        References(x => x.Auswahl)
            .Column("IDAUSWAHL")
            .Not.Nullable();
    

到目前为止,保存到 DB 只适用于空列表 (RefFilters),所以我现在必须研究一下。这是来自我的日志。我真的不知道“NHibernate.Type.Int64Type - binding '1' to parameter: 3 14:31:18.585 [9] DEBUG” 来自哪里,但这是我目前得到的例外。

14:31:18.397 [9] 调试 NHibernate.Persister.Entity.AbstractEntityPersister - 插入实体:[ORMTest.DomainModel.RefAuswahlFilter#ORMTest.DomainModel.RefAuswahlFilter] 14:31:18.413 [9] 调试 NHibernate.AdoNet.AbstractBatcher - 打开新 IDbCommand,打开 IDbCommands:1 14:31:18.413 [9] 调试 NHibernate.AdoNet.AbstractBatcher - 为 SqlString 构建 IDbCommand 对象:INSERT INTO REFAUSWAHLFILTER (Filter, IDAUSWAHL, Filterrank) VALUES (?, ?, ?) 14:31:18.413 [9] 调试 NHibernate.Persister.Entity.AbstractEntityPersister - 脱水实体:[ORMTest.DomainModel.RefAuswahlFilter#ORMTest.DomainModel.RefAuswahlFilter] 14:31:18.413 [9] 调试 NHibernate.Type.StringType - 将“fh”绑定到参数:0 14:31:18.413 [9] 调试 NHibernate.Type.Int64Type - 将“1446”绑定到参数:1 14:31:18.413 [9] 调试 NHibernate.Type.Int64Type - 将“1446”绑定到参数:2 14:31:18.413 [9] 调试 NHibernate.Type.Int64Type - 将“1”绑定到参数:3 14:31:18.585 [9] 调试 NHibernate.AdoNet.AbstractBatcher - 关闭 IDbCommand,打开 IDbCommands:0 14:31:18.647 [9] 调试 NHibernate.AdoNet.ConnectionManager - 注册刷新结束

编辑: 如果我将映射更改为

public RefAuswahlFilterMap()
    
        Table("REFAUSWAHLFILTER");

        CompositeId()
            .KeyReference(x => x.Auswahl,"IDAUSWAHL")
            .KeyProperty(x => x.Filterrank);

        Map(x => x.Filter);
    

按预期保存。然而 NHibernate Profiler 显示了一些警告,我对 RefAuswahlFilter 的选择看起来不太好:)

SELECT reffilters0_.IDAUSWAHL  as IDAUSWAHL1_,
       reffilters0_.Filterrank as Filterrank1_,
       reffilters0_.IDAUSWAHL  as IDAUSWAHL3_0_,
       reffilters0_.Filterrank as Filterrank3_0_,
       reffilters0_.Filter     as Filter3_0_
FROM   REFAUSWAHLFILTER reffilters0_
WHERE  reffilters0_.IDAUSWAHL = 1 /* :p0 */

【讨论】:

以上是关于Nhibernate - 如何使用 CompositeId 设计域对象和映射的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NHibernate 模式生成更新数据库表模式?

如何使用 NHibernate 迭代整个表?

NHibernate - 如何使用 where 子句保存对象

如何使用 MySQL 配置流畅的 nHibernate

Nhibernate - 如何使用 CompositeId 设计域对象和映射

如何使用 NHibernate 检索具有列表条件的元素