流畅的NHibernate Automap约定用于非空字段。

8

有人能帮忙吗,我该如何指示automap使列为非空?

public class Paper : Entity
{
    public Paper() { }

            [DomainSignature]
            [NotNull, NotEmpty]
            public virtual string ReferenceNumber { get; set; }

            [NotNull]
            public virtual Int32 SessionWeek { get; set; }
}

但是我得到了以下内容:
 <column name="SessionWeek"/>

我知道可以使用fluent-map来完成,但我想以自动映射的方式完成。

5个回答

6

谢谢。此外,参考属性需进行参考约定。以下是可行的代码:

public class ColumnNullConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        if (instance.Property.MemberInfo.IsDefined(typeof(NotNullAttribute), false))
            instance.Not.Nullable();
    }

}  public class ReferenceConvention : IReferenceConvention
{
    public void Apply(FluentNHibernate.Conventions.Instances.IManyToOneInstance instance)
    {
        instance.Column(instance.Property.Name + "Fk");


        if (instance.Property.MemberInfo.IsDefined(typeof(NotNullAttribute), false))
            instance.Not.Nullable();

    }
}

1

这是我做的方式,基本上是从代码中看到的链接中获取的。那里还有一些其他有用的约定。

希望对你有所帮助,
Berryl

/// <summary>
/// If nullability for the column has not been specified explicitly to allow NULL, then set to “NOT NULL”.
/// </summary>
/// <remarks>see http://marcinobel.com/index.php/fluent-nhibernate-conventions-examples/</remarks>
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();
    }
}

1
这对我来说效果最好。我还实现了一个类似的约定,用于非空引用,如其他帖子中所述。但是使用此格式。只需更改 IPropertyConvention 和 IPropertyConventionAcceptance 以使用 IReferenceConvention 和 IReferenceConventionAcceptance。 - Matt Johnson-Pint

1

如果您对自动映射的结果大多数情况下感到满意,但偶尔需要覆盖类中的一些属性,我发现为该类实现IAutoMappingOverride是实现这一目标最简单的方法:

public class UserMappingOverride : IAutoMappingOverride<User>
{
      public void Override(AutoMapping<User> mapping)
      {
          mapping.Map(x => x.UserName).Column("User").Length(100).Not.Nullable();
      }
}

然后像这样使用它们:

AutoMap.AssemblyOf<User>().UseOverridesFromAssemblyOf<UserMappingOverride>();

类似于ClassMaps - 但您不需要描述类中的每个字段。 这种方法与实体框架的Code First Fluent API方式非常相似。


0

我发现大多数情况下,我的列都不为空,因此我更喜欢遵循这个约定并仅将列指定为可空:

  /// <summary>
  /// Indicates that a column should allow nulls 
  /// </summary>
  [Serializable]
  [AttributeUsage(AttributeTargets.Property)]
  public class NullableAttribute : Attribute
  {
  }



 public class ColumnIsNotNullByDefaultConvention : IPropertyConvention, IPropertyConventionAcceptance
  {
    public void Apply(IPropertyInstance instance)
    {
      instance.Not.Nullable();
    }

    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
      criteria.Expect(c => !c.Property.MemberInfo.IsDefined(typeof(NullableAttribute), false));
    }
  }

0
public class Paper Map : IAutoMappingOverride<Paper >
{
    public void Override(AutoMapping<Paper> mapping)
    {
        mapping.Map(x => x.ReferenceNumber).Not.Nullable();
    }
}

默认情况下,Int32不是可空类型。 Int32?是可空的,因此您只需将其指定为Int32即可使其变为非可空。

您可以使用约定自动执行此操作。我不确定要使用哪个约定,但请查看FluentNHibernate.Conventions.Instances以找到正确的约定。它将如下所示。

public class ColumnConvention : IColumnConvention
{
    public void Apply(FluentNHibernate.Conventions.Instances.ColumnInstance instance)
    {
        if (instance.EntityType.IsDefined(typeof(NotNullAttribute), false))
            instance.NotNull = true;
    }

    public void Apply(FluentNHibernate.Conventions.Instances.IColumnInstance instance)
    {
        return;
    }
}

只需将此约定添加到您的自动映射中即可。


谢谢,但如果我的应用程序中有许多实体的许多属性都不为空,我该怎么办?我要重写它们吗?但这对我来说似乎不太合适。 - Robi
nHibernate Validator是一个独立的组件。您需要在自动映射中检查该属性。 - Egor Pavlikhin
非常感谢您的回复。 好的。这意味着除了覆盖应用程序的所有属性之外,没有AutoMapping约定可以指示Fluent Nhibernate指定一个字段为非空。这向我表明AutoMap缺少一个非常基本的功能。如果我需要覆盖每个类映射,因为几乎所有类映射都有或多或少的“非空”字段,那么为什么有人要使用自动映射而不是流畅映射呢?请分享您的想法。 - Robi
不,它并没有缺少功能,因为NHibernate Validator不是NHibernate的一部分,而是一个扩展。你不必每次都写它。我已经更新了我的答案,向你展示了你可以做什么。 - Egor Pavlikhin
(instance.EntityType.IsDefined(typeof(NotNullAttribute), false)) 这段代码总是返回 false,导致约定未被应用。我不确定如何检测属性的存在。我也尝试过使用 PropertConvesntion,但问题依旧。感谢您一直以来的支持。 - Robi
好吧,属性在属性上,而不是在类上 -_- 抱歉。 - Egor Pavlikhin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接