代码之家  ›  专栏  ›  技术社区  ›  Venemo

如何微调fluentnhibernate的自动映射程序?

  •  5
  • Venemo  · 技术社区  · 15 年前

    好的,所以昨天我设法让最新的nhibernate和fluentnhibernate主干构建与我的最新小项目一起工作。(我正在开发一个bug跟踪应用程序)我使用repository模式创建了一个不错的数据访问层。

    我认为我的实体没有什么特别之处,而且随着orms目前的成熟,我不想手工构建数据库。 所以,我选择使用fluentnhibernate的自动映射特性,将nhibernate的“hbm2dl.auto”属性设置为“create”。

    它真的很有魅力。我把nhibernate配置放在我的应用程序域的配置文件中,设置它,然后开始使用它。(目前,我只创建了一些单元测试。)它创建了数据库中的所有表,以及我需要的所有表。它甚至正确地映射了我的多对多关系。

    不过,也有一些小问题:

    • 数据库中创建的所有列都允许空值。我知道它无法预测哪些属性应该允许空值,哪些不应该,但至少我想告诉它,它应该只允许那些在.NET中有意义的空值类型(例如,不允许空值类型不应该允许空值)。
    • 它创建的所有nvarchar和varbinary列的默认长度都是255。我宁愿把它们放在马克斯身上而不是那个。

    有没有办法告诉自动映射程序上面的两个简单规则?

    如果答案是否定的,那么如果我修改它创建的表,它会正常工作吗? (因此,如果我将某些列设置为不允许为空,并更改其他列的允许长度,那么它是否可以正确地处理这些列?)

    最后编辑: 非常感谢每一位过来帮忙的人。 我对fluent的所有问题现在都解决了。

    3 回复  |  直到 15 年前
        1
  •  6
  •   Community CDub    8 年前

    可以使用自动映射替代来更改自动映射器的工作方式,也可以定义将由自动映射器使用的约定。

    下面是关于如何同时使用约定和重写的示例:

    var mappings = new AutoPersistenceModel();
    mappings.Conventions.Setup(s => s.Add<ColumnNullabilityConvention>());
    mappings.UseOverridesFromAssemblyOf<AssemblyName>();
    
    // This convention will set all properties to be not nullable
    
    public class ColumnNullabilityConvention: IPropertyConvention, IPropertyConventionAcceptance
    {
       public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
       {
           criteria.Expect(x => x.Nullable, Is.Not.Set);
       }
    
       public void Apply(IPropertyInstance instance)
       {
           instance.Not.Nullable();
       }
    }
    
    // This override will change "string" to use "text" instead of "varchar(255)".
    // Also set the property to be not nullable
    
    public class SomeOverrideInTheSameAssembly : IAutoMappingOverride<TypeName>
    {
       public void Override(AutoMapping<TypeName> mapping)
       {
           mapping.Map(x => x.Property).CustomType("StringClob").CustomSqlType("text");
           mapping.Map(x => x.Property).Not.Nullable();
       }
    }    
    

    有关更多示例,请查看以下链接:

        2
  •  3
  •   James Gregory    15 年前

    对于你的身份证问题,你需要改变 FindIdentity 设置。它包含在 automapping wiki page ,尽管很短暂。

    应该是这样的:

    AutoMap.AssemblyOf<Entity>() // your usual setup
      .Setup(s =>
      {
        s.FindIdentity = m => m.Name == "ID";
      });
    

    这样做的目的是指示自动应用程序使用新的lambda( m => m.Name == "ID" )当试图发现身份证时。 m 是属性/成员,此lambda是为每个实体上的每个属性调用的;为哪个返回true就是id。

        3
  •  1
  •   Tom Bushell    15 年前

    它并不广为人知,但是您可以在配置代码的mappings部分设置许多约定,例如。

    Fluently.Configure()
      .Database(/* database config */)
      .Mappings(m =>
      {
        m.FluentMappings
          .AddFromAssemblyOf<Entity>()
          .Conventions.Add(PrimaryKey.Name.Is(x => "ID"));
      })
    

    设置主键约定。

    编辑: 澄清PrimaryKey公约的作用:

    primarykey约定用于 指定 的 主键是,而不是属性。 发现财产是一件纯粹的事 自动绘图练习,同时 约定应用于类映射 还有自动地图。格雷果里

    这是受支持约定的列表(来自wiki):

    Table.Is(x => x.EntityType.Name + "Table")
    PrimaryKey.Name.Is(x => "ID")
    AutoImport.Never()
    DefaultAccess.Field()
    DefaultCascade.All()
    DefaultLazy.Always()
    DynamicInsert.AlwaysTrue()
    DynamicUpdate.AlwaysTrue()
    OptimisticLock.Is(x => x.Dirty())
    Cache.Is(x => x.AsReadOnly())
    ForeignKey.EndsWith("ID")
    

    The Simplest Conventions 关于fnh wiki的部分。

    推荐文章