3

(Criteria APIを使用して)2つのクラス間のマッピングを指定せずに2つのクラスを結合することは可能ですか?

2つのクラスを結合し、両方からデータを取得する必要がありますが、それらをマッピングできません。最初のクラスでは外部キーSomeID、2番目のクラスでは主キーIDしか知りません。

それらに参加するための基準を作成するにはどうすればよいですか?マッピングなしで可能ですか?

助けてください、私は本当にそれを必要としていますが、私は立ち往生しています。:/

PS

「any」マッピングは知っていますが、SomeIDのような10個のフィールドがあります。結合を作成するためだけに10フィールドのマッピングを作成するのはやり過ぎです。他に解決策がない場合は、それを実行しますが、実行したくありません。

4

2 に答える 2

6

基準のバージョンはわかりませんが、HQL では次のようにできます。

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

結果セットは object[] のリストになり、顧客は彼が行った注文の回数を繰り返します (もちろん、多くの注文に対して 1 人の顧客がいると仮定します)。

オーダーがない場合、結果は空になることに注意してください。

于 2009-02-05T11:36:27.440 に答える
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 に追加するだけです。たとえば、「ProductPartRecord」という名前のテーブルに格納されている「ProductPart」という名前のパーツがある場合、偽のプロパティ「ProductPartRecord」で ContentItem を結合できます。

ちなみに、この戦術は偽のリレーションの HasMany 側にも適用できるようですが、Fluent ソースをカスタマイズする必要があると思います。

于 2012-11-21T23:08:39.120 に答える