1

次のエンティティモデルがあります

public class User
{
        public virtual long Id{get; set;}
        [InverseProperty("Users")]
        public virtual ICollection<Tag> Tags { get; protected set; } 
}

public class Tag
{
        public virtual long Id{get; set;}
        internal protected virtual ICollection<User> Users { get;  set; }
}

これは純粋に単純な多対多の関係です ユーザーとタグ 私はデータ移行を使用しています。コマンド Add-Migration または Update-Database を実行すると、次のエラーが表示されます。関連型 'Kigg.DomainObjects.Entities.Tag' のプロパティ。プロパティが存在し、有効な参照またはコレクション ナビゲーション プロパティであることを確認してください。"

Tag の Users プロパティのアクセス修飾子を public に変更すると、正常に機能し、生成が必要なものになりました。

私の設計の観点からは、Tag.Users プロパティを非表示にし、公開 API に公開したくないため、内部使用のためにそれを保護または内部に保持したいと考えています。

注: ここでは私の設計については説明しません。Tag.Users が保護されているか内部にあるときにそれが可能かどうかを尋ねていますか?

4

2 に答える 2

2

データ注釈で機能させる方法はわかりませんが、Fluent API を使用すると、ここからトリックを適用して実験できます: http://blog.cincura.net/232731-mapping-private-protected-properties-in- entity-framework-4-x-code-first/

モデルの場合、次のようになります。

public class User
{
    public virtual long Id{get; set;}
    public virtual ICollection<Tag> Tags { get; protected set; } 
}

public class Tag
{
    public virtual long Id{get; set;}
    internal protected virtual ICollection<User> Users { get;  set; }

    public class PropertyAccessors
    {
        public static readonly Expression<Func<Tag, ICollection<User>>> Users
            = t => t.Users;
    }
}

FluentAPI でのマッピング:

modelBuilder.Entity<User>()
    .HasMany(u => u.Tags)
    .WithMany(Tag.PropertyAccessors.Users);

これは機能し、期待される多対多の関係を作成します。

しかし、そのナビゲーション プロパティで何か役に立つことができるかどうかはわかりません。protectedプロパティを持っているという事実から、virtual基本的にエンティティ クラスまたは派生クラス内での遅延読み込みのサポートが必要であると推測できます。

public問題は、明らかに(少なくとも私のテストによると)遅延読み込みがプロパティ以外では機能しないことです。読み込まれたタグはプロキシですが、ナビゲーション コレクションは常にnull(プロパティが でない限りpublic) です。

さらに、熱心で明示的な読み込みでさえ機能しません。

Tagクラス外:

// Eager loading
var tag = context.Tags.Include(Tag.PropertyAccessors.Users).First();

// Explicit loading
var tag2 = context.Tags.First();
context.Entry(tag2).Collection(Tag.PropertyAccessors.Users).Load();

またはTagクラス内(Tagコンテキストが渡されるメソッド):

public DoSomething(MyContext context)
{ 
    // Eager loading
    var tag = context.Tags.Include(t => t.Users).First();

    // Explicit loading
    context.Entry(this).Collection(t => t.Users).Load();
}

Usersすべての場合において、エンティティのプロパティTagが有効なナビゲーション プロパティではないという例外が発生します。(プロパティを作成するとすぐに例外が消えますpublic。)

関係の追加/削除/更新が機能するかどうかはわかりません。(私は疑う。)

このアプローチで非パブリック ナビゲーション プロパティをマップして、期待されるデータベース スキーマを生成できるようです。しかし、それでできることは何もないようです。

于 2012-03-26T16:57:06.823 に答える
0

EF5 についてはよくわかりませんが、InternalsVisibleToAttribute属性を使用して、内部メンバーを特定のアセンブリから見えるようにすることができます。

于 2012-03-26T12:23:20.117 に答える