刚刚尝试了一些流畅的NHibernate AutoMap惯例,并遇到了一些我无法弄清楚的事情。我想我只是没找对方的地方...... 基本上试图在一对多关系的“多”方面强制执行NOT-NULL。 看来,使用自动化,它总是使父属性Id在数据库中可以为空。
我在StackOverFlow上做了一些搜索,发现了类似的问题,但是没有任何与AutoMapping和Conventions相关的内容(除非我错过了)。
快速举例......
public class Group // One Group
{
public Group() { this.Jobs = new List<Job>(); }
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Job> Jobs { get; protected set; }
}
public class Job // Has many Jobs
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
// Trying to make this field not-nullable in the database.
public virtual Group Group { get; set; }
}
我以为我能够创建像......这样的约定。
public class OneToManyConvention : IHasOneConvention
{
public void Apply(IOneToOneInstance instance)
{
// Nullable() isn't a valid method...
instance.Not.Nullable();
}
}
但似乎IOneToOnInstance没有Nullable()方法。如果我为Job创建一个Map文件,但是试图避免任何Map文件并坚持使用自动映射,我可以这样做。
我遇到了这个描述类似内容的link on the Fluent group list。
其中描述的内容......
public class NotNullPropertyConvention : IPropertyConvention
{
public bool Accept(IProperty target)
{
return true;
}
public void Apply(IProperty target)
{
target.Not.Nullable();
}
}
但这提出了......的问题 1)我如何确定IProperty是一个Job(或任何返回父级的子属性)
2)它在该页面上提到使用它会覆盖我的手动覆盖,例如。如果一个非常具体的属性链接需要为NULL。这将是一个问题(如果它仍然是一个问题,但如果不首先找出#1就无法测试)
有关于此的任何想法吗?我只是错过了一些东西吗?
仍然没有去。即使以下仍然没有在数据库模式中强制执行Not-Nullable ......
public class FluentConvention : IPropertyConvention
{
public void Apply(IPropertyInstance instance)
{
instance.Not.Nullable();
}
}
虽然它适用于所有其他领域......
/耸肩
有什么想法吗?
虽然这不是我想要的答案,但我确实找到了解决方法...... 我使用的是NHibernate Validator程序集,在该程序集中有一个[NotNull]属性。如果我使用Validator属性修饰了我的类,并在创建模式之前将ValidationEngine与NHibernate相关联,那么它会将FK数据库列标记为Not-Nullable。
public class Job // Has many Jobs
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
[NHibernate.Validator.Constraints.NotNull]
public virtual Group Group { get; set; }
}
如果有人需要NHibernate + ValidationEngine初始化的完整代码,请告诉我。 如果有人有任何信息,仍然在寻找使用纯映射约定路线的方法...
谢谢!
答案 0 :(得分:7)
您可以在Fluenttly.Configure()中将自动映射属性覆盖为AutoMap的一部分。
所以你可以这样做:
.Override<Job>(map => map.References(x => x.Group).Not.Nullable())
如果你有很多需要这个的课程,这并不是很方便。
修改强> 您还可以在实现IAutoMappingOverride的类中指定覆盖,如下所示:
public class JobMappingOverride : IAutoMappingOverride<Job>
{
public void Override(AutoMapping<Job> mapping)
{
mapping.References(x => x.Group).Not.Nullable();
}
}
并将其包括在内:
.UseOverridesFromAssemblyOf<JobMappingOverride>()
这会让您的流畅配置更加清晰。
答案 1 :(得分:0)
似乎只在类的简单属性上调用IPropertyConvention
。如果您的属性引用了另一个类,则还需要使用IReferenceConvention
。
试试这个:
public class FluentConvention : IPropertyConvention, IReferenceConvention
{
public void Apply(IPropertyInstance instance)
{
instance.Not.Nullable();
}
public void Apply(IManyToOneInstance instance)
{
instance.Not.Nullable();
}
}