NHibernate - join without mapping

丶灬走出姿态 提交于 2020-01-03 19:18:36

问题


Is it possible to join two classes without specified mapping between them (using Criteria API)?

I must join two classes and retrieve data from both but I can't mapping them. I know only foreign key SomeID in the first class and primary key ID in second.

How to create Criteria to join them? Is it possible without mapping?

Please, help, I'm really need it but I'm stuck. :/

PS

I know 'any' mapping but I have 10 fields like SomeID. Creating any mappings for 10 fields only for creating joins is overkill. If there is no other resolution I'll do it but I don't want to.


回答1:


I don't know the criteria version, but in HQL you can do it like this:

select customer, order from Customer customer, Order order 
    where order.CustomerID = customer.Id
    and customer.Id = 42

The result set will then be a list of object[] where the customer will be repeated times the number of orders he has placed (assuming of course that there is one customer to many orders).

Please note that the result will be empty if there aren't any ordes.




回答2:


If you don't want to or you can't define the association properties in your entities ( like in modular applications which support dynamic loading of plugins ) , you still can create "fake" associations using the Fluent api.

See Orchard source code, "ContentItemAlteration" class. In Orchard, ContentItem entity is wanted to be joined with ContentPart records stored in different tables. Each ContentPart type is provided by modules which means it is difficult ( and probably not preferred ) to change the source of the ContentItem and add an association for each new part record.

Here is the exact code I got from Orchard sources:

/// <summary>
    /// Add a "fake" column to the automapping record so that the column can be
    /// referenced when building joins accross content item record tables.
    /// <typeparam name="TItemRecord">Either ContentItemRecord or ContentItemVersionRecord</typeparam>
    /// <typeparam name="TPartRecord">A part record (deriving from TItemRecord)</typeparam>
    /// </summary>
    class Alteration<TItemRecord, TPartRecord> : IAlteration<TItemRecord> {
        public void Override(AutoMapping<TItemRecord> mapping) {

            // public TPartRecord TPartRecord {get;set;}
            var name = typeof(TPartRecord).Name;
            var dynamicMethod = new DynamicMethod(name, typeof(TPartRecord), null, typeof(TItemRecord));
            var syntheticMethod = new SyntheticMethodInfo(dynamicMethod, typeof(TItemRecord));
            var syntheticProperty = new SyntheticPropertyInfo(syntheticMethod);

            // record => record.TPartRecord
            var parameter = Expression.Parameter(typeof(TItemRecord), "record");
            var syntheticExpression = (Expression<Func<TItemRecord, TPartRecord>>)Expression.Lambda(
                typeof(Func<TItemRecord, TPartRecord>),
                Expression.Property(parameter, syntheticProperty),
                parameter);

            mapping.References(syntheticExpression)
                .Access.NoOp()
                .Column("Id")
                .ForeignKey("none") // prevent foreign key constraint from ContentItem(Version)Record to TPartRecord
                .Unique()
                .Not.Insert()
                .Not.Update()
                .Cascade.All();
        }
    }

This code simply adds a "part" association to ContentItem which enables you to use joins in your criterias. If for instance, you have a part named "ProductPart" which is stored in a table named "ProductPartRecord", then you can join your ContentItem on fake property "ProductPartRecord".

By the way, it seems this tactic can also be applied to HasMany side of the fake relation but you have to customize the Fluent sources I suppose.



来源:https://stackoverflow.com/questions/515406/nhibernate-join-without-mapping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!