DB2 Fluent NHibernate映射HasMany映射中的重复记录

时间:2013-08-28 20:32:30

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping db2-400

我访问了一个预先存在的数据库(实际上是IBM i上的DB2),并且遇到了Fluent NHibernate中以下(简单)结构的映射问题。我不得不构建一个人为的例子,原谅任何遗漏。

工作......

public class Job
{
    public virtual string JobCode { get; set; }

    public virtual string Owner{ get; set; }

    public virtual IList<Deliverable> Deliverables { get; set; }

    public Job()
    {
        Deliverables = new List<Deliverable>();
    }
}

可交付..

public class Deliverable
{
    public virtual string JobCode { get; set; }

    public virtual int Package { get; set; }

    public virtual string Owner { get; set; }

    public virtual string Reference { get; set; }

    public virtual Job Job { get; set; }
}

我正在尝试在Job和Deliverable之间映射'HasMany'关系,如下所示。

public class JobMap : ClassMap<Job>
{
    public JobMap()
    {
        Table("JOB");

        Id(x => x.JobCode).Column("CODE");

        Map(x => x.Owner).Column("WHODO");

        HasMany(x => x.Deliverables)
            .KeyColumn("CODE");
    }
}

public class DeliverableMap : ClassMap<Deliverable>
{
    public DeliverableMap()
    {
        Table("DELIVERABLE");

        Id(x => x.JobCode).Column("CODE");

        Map(x => x.Reference).Column("UNQREF");

        Map(x => x.Owner).Column("WHODO");

        References( x => x.Job) 
            .Column("CODE") ;
    }
}

这似乎有效,如果您使用生成的SQL并直接运行它,将返回正确的结果(在本例中为11条记录,全部唯一)。但是,当我执行以下操作时,可交付物列表中有11个条目全部相同。

IList结果=会话     .CreateCriteria(typeof运算(工作))     .Add(Expression.Eq(“Code”,“206171”))     .LIST();

foreach (var job in results)
{
   Console.WriteLine("job.JobCode" + job.JobCode);
   Console.WriteLine("job.Owner" + job.Owner);

   foreach (var deliverable in job.Deliverables)
   {

     **// These are all identical!**

     Console.WriteLine(deliverable.Reference);
     Console.WriteLine("deliverable.Owner" + deliverable.Owner);
     Console.WriteLine(deliverable.JobNumber);
     Console.WriteLine(deliverable.DeliverableTyoe);
     Console.WriteLine(deliverable.Description);
   }
}

那么,映射是否不正确,或者是否存在我使用它们的方式?

非常感谢,我一整天都在盯着这个。

2 个答案:

答案 0 :(得分:2)

我似乎修好了它。我将CompositeID添加到Deliverables贴图

 CompositeId()
     .KeyProperty(x => x.JobCode, "CODE")
     .KeyProperty(x => x.Reference, "UNQREF");

这意味着我必须在Deliverable类中重写以下内容

public override bool Equals(object obj)
{
  if (obj == null)
    return false;

  var t = obj as Deliverable;
  if (t == null)
    return false;

  if (JobCode == t.JobCode && Reference == t.Reference)
    return true;

  return false;
 }

  public override int GetHashCode()
  {
    return (JobCode + "|" + Reference).GetHashCode();
  }

然后还更改了作业映射,如下所示

 HasMany(x => x.Deliverables)
   .KeyColumn("Codex")
   .Inverse()
   .Cascade.All();

我不确定其中哪些更正了这种情况(我怀疑作业映射中的.Inverse()

我不确定生成的SQL现在是什么样的,但答案看起来是正确的。

答案 1 :(得分:1)

在多对一关系中(在我们的案例中为DelivarableJob),关系本身用一个数据库列表示。子表(Deliverable)具有(必须具有)具有作业 ID(代码)的引用列。

因此,我们的映射需要的是Delivarable表中的列,其中包含与Job的关系。 JobCode列。public DeliverableMap() { ... // References( x => x.Deliverable) ... I guess it is typo in the question snippet References( x => x.Job) .Column("JobCode") ; // column of table Deliverable } 。 (不确定是否有任何,例如上面的例子)

这必须在双方都使用:

Delivarable:

public JobMap()
{
    ...
    HasMany(x => x.Deliverables)
        .KeyColumn("JobCode");  // column of table Deliverable
}

作业:

Deliverable

换句话说,此映射中的两个列名实际上都是一个列的名称。两者都映射到子(可交付)表的列。

EXTENDED:基于问题中的映射变化

ID对象的Job(列CODE)与{{1}}(列CODE)的引用相同。这似乎很奇怪。

这也解释了这样一个事实,即JOB集合中的所有可交付项目都是相同(相同)。 Unique Deliverable(由其CODE定义)只能是一个。此场景中的Job不能有多个Deliverable(因为它由唯一的CODE列引用)。它似乎是一对一的场景。

更多相同的原因更难判断。很高兴看到你正在使用的查询。

但我真的会两次检查列映射。可交付的,应该在名为“JobCODE”的列中引用Job ...支持更多Delivrables相关...