データ注釈で機能させる方法はわかりませんが、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
。)
関係の追加/削除/更新が機能するかどうかはわかりません。(私は疑う。)
このアプローチで非パブリック ナビゲーション プロパティをマップして、期待されるデータベース スキーマを生成できるようです。しかし、それでできることは何もないようです。