简体   繁体   English

流畅的NHibernate强制在外键引用上不可为空

[英]Fluent NHibernate enforce Not Nullable on Foreign Key Reference

Just getting my feet wet with some Fluent NHibernate AutoMap conventions, and ran into something I couldn't figure out. 刚刚尝试了一些流畅的NHibernate AutoMap惯例,并遇到了一些我无法弄清楚的问题。 I assume I'm just not looking in the right place... Basically trying to enforce NOT-NULL on the "many" side of the one to many relationship. 我假设我只是没有找到正确的位置...基本上尝试在一对多关系的“多”方面强制执行NOT-NULL。 It seems, using the automapping, it always makes the parent property Id nullable in the database. 看来,使用自动化,它总是使父属性Id在数据库中可以为空。

I did some searching on StackOverFlow and found similar questions, but nothing relating to AutoMapping and Conventions though (unless I missed it). 我在StackOverFlow上做了一些搜索,发现了类似的问题,但是没有任何与AutoMapping和Conventions相关的内容(除非我错过了)。

Quick example... 快速举例......

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; }
}

I thought I'd be able to just create a convention like... 我以为我能够创建像......这样的会议

public class OneToManyConvention : IHasOneConvention
{
    public void Apply(IOneToOneInstance instance)
    {
        // Nullable() isn't a valid method...
        instance.Not.Nullable();   
    }
}

But it seems IOneToOnInstance doesn't have a Nullable() method. 但似乎IOneToOnInstance没有Nullable()方法。 I can do this if I create a Map file for Job, but trying to avoid any Map files and stick with auto-mapping. 我可以这样做,如果我为Job创建一个Map文件,但试图避免任何Map文件并坚持使用自动映射。

I came across this link on the Fluent group list describing something similar. 在Fluent组列表中看到了这个链接,描述了类似的内容。

Which describes something like this... 其中描述的是这样的......

public class NotNullPropertyConvention : IPropertyConvention
{
    public bool Accept(IProperty target)
    {
            return true;
    }
    public void Apply(IProperty target)
    {
            target.Not.Nullable();
    }
}

But that raises the questions of... 1) How would I determine IProperty to be a Job (or any child property that is a link back to the parent) 但这提出了以下问题:1)我如何确定IProperty是一个Job(或任何子属性,是一个回到父级的链接)

2) It made a mention on that page that using this would override my manual overrides, eg. 2)它在该页面上提到使用它会覆盖我的手动覆盖,例如。 if a very specific property link needed to be NULL. 如果一个非常具体的属性链接需要为NULL。 Which would be an issue (if it's still an issue, but can't test without figuring out #1 first) 这将是一个问题(如果它仍然是一个问题,但不能先测试#1而无法测试)

Any ideas on this? 有什么想法吗? Am I just missing something? 我只是错过了一些东西吗?



Update 1 更新1

Still no go. 仍然没有去。 Even the following still doesn't enforce Not-Nullable in the database schema... 即使以下仍然没有在数据库模式中强制执行Not-Nullable ......

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

It does for all of the other fields though... 它适用于所有其他领域......
/shrug /耸肩

Any ideas? 有任何想法吗?



Update 2 更新2

While this isn't the answer I was looking for, I did find a work around... I was using NHibernate Validator assembly, and within that assembly there is a [NotNull] attribute. 虽然这不是我想要的答案,但我确实找到了解决方法......我正在使用NHibernate Validator程序集,并且在该程序集中有一个[NotNull]属性。 If I decorated my class with the Validator attribute, and associated the ValidationEngine to NHibernate before the schema creation, it would tag the FK database column as Not-Nullable. 如果我使用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; } } 

If anyone needs the full code for the NHibernate + ValidationEngine initialization, just let me know. 如果有人需要NHibernate + ValidationEngine初始化的完整代码,请告诉我。 Still looking for a way to do it using the pure mapping convention route though if anyone has any info... 如果有人有任何信息,仍然在寻找使用纯映射约定路线的方法...

Thanks! 谢谢!

You can override the auto-mapped properties as part of your AutoMap in Fluenttly.Configure(). 您可以在Fluenttly.Configure()中将自动映射属性覆盖为AutoMap的一部分。

So you can do this: 所以你可以这样做:

.Override<Job>(map => map.References(x => x.Group).Not.Nullable())

It's not exactly convenient if you have a lot of classes that need this though. 如果你有很多需要这个的课程,这并不是很方便。

Edit: You can also specify the override in a class that implements IAutoMappingOverride like so: 编辑:您还可以在实现IAutoMappingOverride的类中指定覆盖,如下所示:

    public class JobMappingOverride : IAutoMappingOverride<Job>
    {
            public void Override(AutoMapping<Job> mapping)
            {
                    mapping.References(x => x.Group).Not.Nullable();
            }
    }

and include it like so: 并包括它:

    .UseOverridesFromAssemblyOf<JobMappingOverride>()

This would keep your fluent configuration a little cleaner. 这将使您的流畅配置更清洁。

It seems that IPropertyConvention is only called on simple properties of your classes. 似乎只对类的简单属性调用IPropertyConvention If your property references another class, you need to use IReferenceConvention too. 如果您的属性引用了另一个类,则还需要使用IReferenceConvention

Try this: 尝试这个:

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

    public void Apply(IManyToOneInstance instance)
    {
        instance.Not.Nullable();
    }
}      

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM