エンティティで関連付けプロパティを定義したくない、または定義できない場合 (プラグインの動的読み込みをサポートするモジュラー アプリケーションなど) は、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 ソースをカスタマイズする必要があると思います。