流畅的NHibernate多对一映射问题

时间:2011-09-09 11:08:18

标签: fluent-nhibernate nhibernate-mapping

修改

我有答案,明天会发布。

我有一个类似乎使用父主键列而不是它自己的主键列。

ActionHistory和ActionData涉及两个类。父类ActionHistory表示执行操作的操作和详细信息。子类ActionData表示由操作创建的一段数据。每个ActionHistroy都有许多ActionData,这通过多对一映射表示。

课程是:

public class ActionHistory
{
    public virtual int Code { get; set; } 
    public virtual string Doneby { get; set; }
    public virtual IList<ActionData> _ActionData{ get; set;}
}

public class ActionData
{
    public virtual int Code { get; set; }
    public virtual double Data{ get; set; }
    public virtual ActionHistory _ActionHistory{ get; set; }
}

我的映射是:

public class ActionHistoryClassMap : ClassMap<ActionHistory>
{
    public ActionHistoryClassMap ()
    {
        Table("ACTIONHISTORY");
        Id(x => x.Code, "CODE").GeneratedBy.Assigned();
        Map(x => x.Doneby, "DONEBY");
        HasMany(x => x._Actiondata).KeyColumn("CODE").AsBag().Cascade.All();
    }
}

public class ActionDataClassMap : ClassMap<ActionData>
{
    public ActionDataClassMap ()
    {
        Table("ACTIONDATA");
        Id(x => x.Code, "CODE").GeneratedBy.Assigned();
        Map(x => x.Data, "DATA");
        References(x => x._ActionHistory, "ACTIONHISTORYID");
    }
}

问题是当查询ActionHistory类时,返回了正确的ActionHistory但它包含的HistoryData是错误的。应返回HistoryData列表,但只返回一个HistoryData,其Code值是父ActionHistory类的Code值。我相信我的问题源于这两个类具有相同的主键列名称并且我没有正确处理它。相关的列是ACTIONHISTORY表中的CODE和ACTIONDATA表中的ACTIONHISTORYID。数据库已修复,因此我无法重命名任何列。在这种情况下,数据仅从数据库中读取,不会保存或更新。

我下载了NHibernate Profiler来帮助我解决这个问题,并在SQL中找到问题所在的确切位置。

这是为返回ActionData而生成的SQL查询(其中18是ActionHistory主键):

SELECT actiondat0_.CODE              as CODE1_,
   actiondat0_.CODE              as CODE9_0_,
   actiondat0_.DATA              as DATA9_0_,
   actiondat0_.ACTIONHISTORYID  as ACTIONHI4_9_0_
FROM   ACTIONDATA actiondat0_
WHERE  actiondat0_.CODE = 18 /* @p0 */

最后一行应该是:

WHERE  actiondat0_.ACTIONHISTORYID = 18 /* @p0 */

但我只是不明白为什么映射没有生成正确的查询。

1 个答案:

答案 0 :(得分:0)

我知道这是一件非常明显的事情,经过几个小时无处可去,它当然会跳出来。

ActionHistory类映射当然应该是:

public class ActionHistoryClassMap : ClassMap<ActionHistory>
{
    public ActionHistoryClassMap ()
    {
        Table("ACTIONHISTORY");
        Id(x => x.Code, "CODE").GeneratedBy.Assigned();
        Map(x => x.Doneby, "DONEBY");
        HasMany(x => x._Actiondata).KeyColumn("ACTIONHISTORYID")
            .AsBag().Cascade.All();
    }
}

KeyColumn方法的不同之处现在是ACTIONHISTORYID而不是CODE。我没有警告KeyColumn应该引用ActionHistory键列。现在看起来很明显,并且在我在这个项目中实现它的所有其他时间中,关系中的列总是具有相同的名称,这没有任何帮助。