2

我访问了一个预先存在的数据库(实际上是 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 结果 = session .CreateCriteria(typeof(Job)) .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);
   }
}

那么,映射是否不正确,或者我使用它们的方式有什么问题?

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

4

2 回答 2

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()在 Job mapping.

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

于 2013-08-29T20:46:46.107 回答
1

在多对一关系中(在我们的例子中DelivarableJob),关系本身只用一个DB 列表示。子表 ( 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
}

工作:

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

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

扩展:基于问题中的映射变化

Deliverable对象的ID(列代码)与对(列代码)的引用相同Job。这似乎很奇怪。

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

相同项目越的原因越难判断。很高兴看到您正在使用的查询。

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

于 2013-08-29T03:25:38.013 回答