6

これはおそらく、EF Code Firstの流暢なAPIに関する知識が不足しているためですが、困惑しています。

以下をモデル化したい:

  • IDと名前を持つグループコレクション
  • IDと名前を持つUsersコレクション
  • 各ユーザーは、正確に1つのプライマリグループに割り当てられます
  • 各ユーザーは、ゼロまたは多数のセカンダリグループを持つことができます

私が目指しているテーブル構造は次のようになります。

グループ

  • Id
  • 名前

ユーザー

  • Id
  • 名前
  • PrimaryGroupId

SecondaryGroupAssignments

  • ユーザーID
  • GroupId

EFコードファーストでこれをモデル化しようとして壁に頭をぶつけてきましたが、ユーザーとグループの両方の関係を受け入れることができません。.NETコードを投稿しなかったことをお詫びします(私は喜んでいます)が、とにかくそれはおそらくすべて間違っています。

EFモデルをこれにする方法はありますか?FluentAPIを使用して何らかの構成を行う必要があると想定しています。たぶんもっと良い質問は、Fluent APIの良い、決定的なリファレンスはありますか?

ありがとう!

4

2 に答える 2

16

これを試してください(テストされていません):

public class Group 
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<User> PrimaryUsers { get; set; }
    public virtual ICollection<User> SecondaryUsers { get; set; } 
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int PrimaryGroupId { get; set; }

    public virtual Group PrimaryGroup { get; set; }
    public virtual ICollection<Group> SecondaryGroups { get; set; }
}

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Group> Groups { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<User>()
                    .HasRequired(u => u.PrimaryGroup)
                    .WithMany(g => g.PrimaryUsers)
                    .HasForeignKey(u => u.PrimaryGroupId)
                    .WillCascadeOnDelete(false);

        modelBuilder.Entity<User>()
                    .HasMany(u => u.SecondaryGroups)
                    .WithMany(g => g.SecondaryUsers)
                    .Map(m => m.MapLeftKey("UserId")
                               .MapRightKey("GroupId")
                               .ToTable("SecondaryGroupAssignments"));
    }
}
于 2011-06-03T15:02:42.183 に答える
3

Ladislavの優れた回答に基づいて、マッピングを使用せずにそれを行う方法を次に示します。モデルクラス自体に適用される属性のみです。

public class Group 
{
    public int Id { get; set; }

    [MaxLength(300)]
    public string Name { get; set; }

    public ICollection<User> Users { get; set; }
}

public class User
{
    public int Id { get; set; }

    [MaxLength(300)]
    public string Name { get; set; }

    [ForeignKey("PrimaryGroup")]
    public int PrimaryGroupId { get; set; }
    [Required]
    public Group PrimaryGroup { get; set; }

    [InverseProperty("Users")]
    public ICollection<Group> SecondaryGroups { get; set; }
}

ノート

ICollection必要に応じて、仮想キーワードを2とに追加できますGroup。これにより、遅延読み込みが可能になります。パフォーマンスの面ではお勧めしませんが、可能です。

MaxLengthなしでEFに文字列を出力するとパフォーマンスの低い列が得られるためMaxLength、任意の(ただし安全な)長さの属性を含めました。質問されている内容とはまったく関係ありませんが、適切なコードを投稿することをお勧めします。300NVarChar(MAX)

EFクラスのクラス名は「User」と「Group」にすることをお勧めします。それらは、後で実行しようとするSQLを複雑にし、それらにアクセスするには[User]と[Group]と入力する必要があり、MVCコントローラーでこれらのクラスを使用すると複雑になります。MVCコントローラーでは、クラスがアクセスを許可するプロパティUserと競合します。 Asp.NetIdentityライブラリ。ContextUser

于 2013-10-01T04:43:22.653 に答える