C#Fluent NHibernate 0-1 0-many 1-many使用自定义规则进行映射

时间:2017-07-13 07:14:33

标签: c# nhibernate fluent-nhibernate nhibernate-mapping

我需要使用Fluent库为我的数据库的某些关系配置NHibernate Mappings。 我在VS 2017上使用 NHibernate v4.1.1.4000 FluentNHibernate v2.0.3 创建了 Web Api MVC 项目。

我是那些表:

  • 类型(ID,描述,...,ExpressionId)
  • 表达式(Id,名称,脚本,语言)

关系:

  • 1类型可以引用0或1表达式
  • 1表达式可以通过0或N类型学
  • 引用

我需要配置映射,以便操作我可以的对象:

  1. 更改Expression上引用的Typology,并对其进行更新,以便在数据库中更改ExpressionId列的值。
  2. 删除对ExpressionTypology的引用,以便 ExpressionId NULL以及相应的Expression 保留在数据库中,即使它未被任何其他 Typology引用。
  3. 创建一个新的Expression对象,并将其与现有(或新创建的)Typology关联,以便将新的Expression保存到数据库和Typology(最终创建)参考它,像这样:
  4. Typology typology = _repositoryTypologies.GetById(1);
    
    Expression newExp = new Expression()
    {
        Name = "S2",
        Script = "public void Test()",
        //...
        Language = "cs"
    };
    
    typology.CompletionScript = newExp;
    _repositoryTypologies.Save(typology);
    
    1. 如果可能,如果我删除了Expression,则所有引用该类型的类型都将使用ExpressionId = NULL进行更新。
    2. 我已尝试过一些映射但我没有获得所需的结果。 我在这里和那里看了一下,但我不明白这个案例的最佳映射是什么。有人使用References(),即使有0-1关系,其他人也建议使用HasOne() / HasMany()

      这些是我的实际课程:

      public class Typology
      {
          [Key]
          public virtual int Id { get; protected set; }
          [Required]
          public virtual string Description { get; set; }
          //...
          public virtual Expression CompletionScript { get; set; }
      }
      
      public class TypologyMap : ClassMap<Typology>
      {   
          public TypologyMap()
          {
              Table("Typologies");
              LazyLoad();
              Id(x => x.Id).GeneratedBy.Identity().Column("TypologyId");
              Map(x => x.Description).Column("Description").Not.Nullable();
              //...
              HasOne(x => x.CompletionScript).Cascade.SaveUpdate();
          }
      }
      
      public class Expression
      {
          [Key]
          public virtual int Id { get; protected set; }
          [Required]
          public virtual string Name { get; set; }
          public virtual string Script { get; set; }
          public virtual string Language { get; set; }
      }
      
      public class ExpressionMap : ClassMap<Expression>
      {   
          public ExpressionMap()
          {
              Table("Expressions");
              LazyLoad();
              Id(x => x.Id).GeneratedBy.Identity().Column("ExpressionId");
              Map(x => x.Name).Column("Name").Not.Nullable();
              Map(x => x.Script);
              Map(x => x.Language);
          }
      }
      

1 个答案:

答案 0 :(得分:0)

您的Expression需要某种相关Topologies的收藏品。像这样:

public class Expression
{
    [Key]
    public virtual int Id { get; protected set; }
    [Required]
    public virtual string Name { get; set; }
    public virtual string Script { get; set; }
    public virtual string Language { get; set; }

    // At its most basic...
    public virtual List<Topology> Topologies { get; set; }
}

然后你可以映射它:

public class ExpressionMap : ClassMap<Expression>
{   
    public ExpressionMap()
    {
        Table("Expressions");
        LazyLoad();
        Id(x => x.Id).GeneratedBy.Identity().Column("ExpressionId");
        Map(x => x.Name).Column("Name").Not.Nullable();
        Map(x => x.Script);
        Map(x => x.Language);

        HasMany(x => x.Topologies);
    }
}

您应该能够在映射的References()侧使用Expression。虽然有些人可能会推荐ManyToOne()。我不太确定他们的细微差别。

虽然这应该提供功能性解决方案,但您需要通过考虑访问集合,级联等来加强它。