0

私はEFにかなり慣れておらず、バージョン6を使用しており、1対1の関係に固執しています。私の全体的な構造は、内部に GalleryMediaItem エンティティの ICollection を持つ Gallery オブジェクトがあり、各 GalleryMediaItem にはそれに関連付けられた MediaItem エンティティがあります。GalleryMediaItem エンティティには、基礎となる MediaItem に値があるという要件があることに注意してください。ただし、MediaItem エンティティ自体は GalleryMediaItem を認識していません。これは、MediaItem エンティティが GalleryMediaItem 以外のものに関連付けられる可能性があるため、意図的なものです。次に例を示します。

Gallery
    ---> ICollection<GalleryMediaItems>
             ---> [other properties]
             ---> MediaItem [has no knowledge of GalleryMediaItem]

私がやろうとしているのは、インスタンスMediaItemからプロパティにアクセスするときに、MediaItem エンティティに対して遅延読み込みを機能させることです。GalleryMediaItem私のデータベース構造は上記のコード構造と一致し (GalleryMediaItem には GalleryId と MediaItemId がありますが、MediaItem には GalleryMediaItemId はありませんし、そうすべきでもありません)、返されるオブジェクトは一貫して null です。ここでの奇妙な点はMediaItemId、インスタンスのプロパティGalleryMediaItemが正しく設定されているのに、ナビゲーション プロパティ自体が機能しないことです。次のすべてのバリアントを試してみましたが、うまくいきませんでした。

HasRequired(p => p.MediaItem).WithOptional();
HasRequired(p => p.MediaItem).WithMany();

等々。試したすべてのバリアントでエラーが発生することはありません。ナビゲーション プロパティにアクセスできないだけです。

GalleryMediaItemMediaItemエンティティを入力できるがMediaItem、それ自体では (POCO 経由とデータベースの両方で) 親所有者の知識がない場合に、これを構成する適切な方法は何ですか?

編集

コメントの 1 つで、個々のアイテムを取得するために使用されているコードを表示するよう求められました。DbContext インスタンスの上に汎用フレームワークがありますが、その下には単一のGalleryエンティティを取得するためのメソッドがあります。

    /// <summary>
    /// Retrieves an entity based on the Id parameter.
    /// </summary>
    /// <typeparam name="E">The type of BaseEntity being retrieved.</typeparam>
    /// <param name="Id">The Id to retrieve.</param>
    /// <returns>A BaseEntity of type E if a match is found, otherwise null.</returns>
    public virtual E GetById<E>(long Id)
        where E : BaseEntity
    {
        var whereClause = DataUtilities.BuildOrExpressionTree<E, long>(new long[] { Id }, entity => entity.Id);
        IQueryable<E> entities = this.GetTable<E>().Where(whereClause);

        if (entities.Count() == 1)
            return entities.First();
        else
            return null;
    }

上記のBaseEntityジェネリックは、Id、CreateDate、MaintDate などを含む超基本的な POCO です。私の POCO クラスはいずれも、対応する DB 値の属性を使用せず、すべてが流動的な EF API を介して行われます。Gallery直接継承するBaseEntityため、この汎用関数は期待どおりに機能します。

関数は次のDataUtilities.BuildOrExpressionTreeようになります。

    public static Expression<Func<TValue, bool>> BuildOrExpressionTree<TValue, TCompareAgainst>(IEnumerable<TCompareAgainst> list, Expression<Func<TValue, TCompareAgainst>> convertBetweenTypes)
    {
        ParameterExpression inputParam = convertBetweenTypes.Parameters[0];
        var binaryExpressionTree = BuildBinaryOrTree(list.GetEnumerator(), convertBetweenTypes.Body, null);
        return Expression.Lambda<Func<TValue, bool>>(binaryExpressionTree, new [] { inputParam });
    }

    private static Expression BuildBinaryOrTree<T>(IEnumerator<T> itemEnumerator, Expression expressionToCompareTo, Expression expression)
    {
        if (itemEnumerator.MoveNext() == false)
            return expression;

        ConstantExpression constant = Expression.Constant(itemEnumerator.Current, typeof(T));
        BinaryExpression comparison = Expression.Equal(expressionToCompareTo, constant);

        BinaryExpression newExpression;

        if (expression == null)
            newExpression = comparison;
        else
            newExpression = Expression.OrElse(expression, comparison);

        return BuildBinaryOrTree(itemEnumerator, expressionToCompareTo, newExpression);
    }
4

1 に答える 1

0

使用する場合

HasRequired(p => p.MediaItem).WithMany();

あなたはforeignkeyプロパティを表示する必要があります:

HasRequired(p => p.MediaItem).WithMany().HasForeignKey(p=>p.MediaItemId);

HasRequired(p => p.MediaItem).WithOptional(); で 外部キーも表示する必要がありますが、この場合はForeignKeyAttribute、またはメソッドを使用できますMap

于 2014-11-26T22:19:11.830 に答える