NHibernate - 没有映射的连接

时间:2009-02-05 10:51:29

标签: nhibernate join reference mapping

是否可以在没有指定映射的情况下连接两个类(使用Criteria API)?

我必须加入两个类并从两者中检索数据,但我无法映射它们。我知道第一个类中只有外键 SomeID ,第二个类中只有主键 ID

如何创建条件加入它们?没有映射可以吗?

请帮助,我真的需要它,但我被困住了。 :/

PS

我知道'任何'映射,但我有10个像SomeID的字段。仅为创建联接而创建10个字段的任何映射都是过度的。 如果没有其他解决方案我会做,但我不想。

2 个答案:

答案 0 :(得分:6)

我不知道标准版本,但在HQL中你可以这样做:

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

结果集将是一个对象[]的列表,其中客户将重复他所下订单的数量(假设当然有一个客户到多个订单)。

请注意,如果没有任何ordes,结果将为空。

答案 1 :(得分:1)

如果您不想或者您无法在实体中定义关联属性(例如在支持动态加载插件的模块化应用程序中),您仍然可以使用Fluent api创建“假”关联。

请参阅Orchard源代码,“ContentItemAlteration”类。在Orchard中,希望ContentItem实体与存储在不同表中的ContentPart记录连接。每个ContentPart类型都由模块提供,这意味着更改ContentItem的源并为每个新部件记录添加关联很困难(也可能不是首选)。

以下是我从Orchard来源获得的确切代码:

/// <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();
        }
    }

此代码只是向ContentItem添加“部分”关联,使您可以在标准中使用连接。例如,如果您有一个名为“ProductPart”的零件存储在名为“ProductPartRecord”的表中,那么您可以将您的ContentItem加入假属性“ProductPartRecord”。

顺便说一句,似乎这种策略也可以应用于伪造关系的HasMany方面,但你必须自定义我认为的Fluent来源。