【问题标题】:How to map two tables to each other in nHibernate如何在 nHibernate 中将两个表相互映射
【发布时间】:2015-03-17 08:40:21
【问题描述】:

我正在尝试在我的 MVC 项目中的两个表之间建立查找,其中 nHibernate 被大量使用。我已经映射了两个表,只要我将它们视为单独的实体,它就可以很好地工作。但现在我需要在加载 table1 时以一对一映射从 table2 中提取数据的能力。

Lead.cs

using System;
using FluentNHibernate.Mapping;

namespace SMSService.Models
{
    //Table One
    public class Leads
    {
        public virtual int Id { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string TaskName { get; set; }

        //The second table
        public virtual Workflow Workflow { get; set; }
    }

    public class LeadsClassMap : ClassMap<Leads>
    {
        public LeadsClassMap()
        {
            Table("Leads");
            Id(x => x.Id).GeneratedBy.Native();
            Map(x => x.FirstName);
            Map(x => x.LastName);
            Map(x => x.TaskName);

            //My attempt to join the tables
            HasOne(x => x.Workflow).Column("LeadId");
        }
    }
}

Workflow.cs

using System;
using FluentNHibernate.Mapping;

namespace SMSService.Models
{
    //Table Two
    public class Workflow
    {
        public virtual int Id { get; set; }
        public virtual int LeadId { get; set; }
        public virtual bool PreviouslySubmitted { get; set; }
        public virtual Guid SubmittedBy { get; set; }
        public virtual DateTime Modified { get; set; }
        public virtual int WorkflowStep { get; set; }
    }

    public class WorkflowClassMap : ClassMap<Workflow>
    {
        public WorkflowClassMap()
        {
            Table("Workflow");
            Id(x => x.Id).GeneratedBy.Native();
            Map(x => x.LeadId);
            Map(x => x.PreviouslySubmitted);
            Map(x => x.SubmittedBy);
            Map(x => x.Modified);
            Map(x => x.WorkflowStep);
        }
    }
}

那么,我的目标是,我可以有一个调用 Leads 和 Workflows 的方法,这样我就可以执行以下操作:

foreach (var lead in Leads) {
    var prevSubmitted = lead.Workflow.PreviouslySubmitted;
}

然而,我遇到的第一个问题是在代码中出现“.Column”红色标记,错误为“无法解析符号'Column'”。所以我不确定我的语法是否完全错误,或者我在某处遗漏了一些关键。

【问题讨论】:

    标签: c# nhibernate model-view-controller


    【解决方案1】:

    这似乎不是真正的一对一关系。真正的一对一关系共享相同的主键,这里不是这种情况。

    这似乎是多对一的,而不是应该像下面这样映射。我还要说,通常我不只映射 id 列。如果这是数据库中的外键,它应该与实际的休眠实体相关联,而不仅仅是一个 id。在 nhibernate 中进行查询时,这变得非常宝贵。我在 Workflow 类中更改了下面的 LeadId 以匹配它。

    public class Leads
    {
        public virtual int Id { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string TaskName { get; set; }
    
        //The second table
        public virtual IList<Workflow> Workflows { get; set; }
    }
    
    public class LeadsClassMap : ClassMap<Leads>
    {
        public LeadsClassMap()
        {
            Table("Leads");
            Id(x => x.Id).GeneratedBy.Native();
            Map(x => x.FirstName);
            Map(x => x.LastName);
            Map(x => x.TaskName);
    
            //My attempt to join the tables
            HasMany(x => x.Workflows)
                .KeyColumn("LeadId")
                .Cascade.All();
        }
    }
    
    public class Workflow
    {
        public virtual int Id { get; set; }
        public virtual Leads Lead { get; set; }
        public virtual bool PreviouslySubmitted { get; set; }
        public virtual Guid SubmittedBy { get; set; }
        public virtual DateTime Modified { get; set; }
        public virtual int WorkflowStep { get; set; }
    }
    
    public class WorkflowClassMap : ClassMap<Workflow>
    {
        public WorkflowClassMap()
        {
            Table("Workflow");
            Id(x => x.Id).GeneratedBy.Native();
            References(x => x.Lead, "LeadId");
            Map(x => x.PreviouslySubmitted);
            Map(x => x.SubmittedBy);
            Map(x => x.Modified);
            Map(x => x.WorkflowStep);
        }
    }
    

    【讨论】:

    • 实际上是 1:1,只是没有强制约束。对于 Lead 中的每条记录,Workflow 中将始终存在且只能有 1 条记录。工作流具有“LeadId”的原因主要是因为我希望防止在记录可能从一个表中删除而不是从另一个表中删除时出现任何错误(在开发环境中,这种情况经常发生)。
    • 我仍然不同意你说这是 1-1。看看jagregory.com/writings/i-think-you-mean-a-many-to-one-sir。无论如何,您仍然可以将上述映射更改为 References(x =&gt; x.WorkFlow, "LeadId") 并将集合 public virtual IList&lt;Workflow&gt; Workflows { get; set; } 更改为 public virtual Workflow Workflow { get; set; } 以实现您想要的。如果没有什么可以阻止您在 Workflow 中有多个具有相同 LeadId 的记录,我预计最终会遇到问题。
    【解决方案2】:

    在这种情况下,一对一映射不起作用,因为它们使用的 ID 不同,因此一种解决方法是,

    References(x => x.Workflow).Column("LeadId");
    

    【讨论】:

      猜你喜欢
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 2010-12-23
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      相关资源
      最近更新 更多