Unidirectional parent-child association not null

2019-08-04 08:12发布

问题:

I have a class structure which is akin to a PurchaseOrder (parent) and PurchaseOrderLine (child) pattern, where the order lines will only be saved to the DB by saving the parent PurchaseOrder and will only ever be accessed via the parent too.

The DB has PurchaseOrderLine.PurchaseOrder set to not permit null values.

It seems from searching through the web that it is not possible to have a uni-directional association from PurchaseOrder via an IList property without having to have a property on the line pointing back when the child has a NOT NULL constraint for its PurchaseOrder column.

Is this really the case? It seems like one of the most basic things one would want to do with an ORM, I find it difficult to accept that a product as mature as NHibernate cannot handle such a basic scenario.

回答1:

No it's not the case. Please see the example provided in the answer to this question: When to use inverse=false on NHibernate / Hibernate OneToMany relationships?



回答2:

Well, it may be the case that you can't have unidirectional one-to-many relationship defined only on one side, but I'll argue with your statement that this is "one of the most basic things one would want to do with an ORM".

One of the most basic things would be to have unidirectional one-to-many defined only on many side - as it is natural for RDBM tables. And ORMs (despite the common misconception) are not intended (or able) to fully abstract domain model from underlying data source. Even if in some cases they can, the database side suffers from select N+1 problems or very ineffective queries.

Defining one-to-many at one side makes an impression that i.e. counting the collection is cheap. It is the case with plain object graphs, but not with NHibernate entities, as reading collection causes (at least one) call to the database. Eager fetching from one side is also not able to properly use database join mechanism in the way it's intended to be used (opposite to eager fetch from many side).

Even if I don't agree with a lot of arguments, I think it is useful to read some of the articles saying that "ORM is an anti-pattern", like this one. They helped me to leverage the way I think about ORMs and make me think about ORMs as a compromise between two not matching paradigms, but not the way to hide one behind another.



回答3:

This can now be achieved in NH3 using the Not.KeyNullable()

        this.HasMany(x => x.Actions)
            .Access.BackingField()
            .KeyColumn("[Application]")
            .Not.KeyNullable()
            .Cascade.AllDeleteOrphan();