0

ASP.NET MVC4 で多対多の関係を設定したいと考えています。目標は、ユーザーに属するオブジェクトUserProfileのリストでデフォルト クラスを拡張することです。は複数のユーザーによって共有される可能性があるため、Timelineクラスにはオブジェクトのリストも必要です。TimelineTimelineUserProfile

タイムライン クラス:

namespace MvcApplication1.Models
{
    public class Timeline
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Color { get; set; }
        public List<UserProfile> Users { get; set; }
    }

    public class TimelineContext : DbContext
    {
        public DbSet<Timeline> Timelines { get; set; }
        public DbSet<UserProfile> UserProfiles { get; set; }

        // Added the following because I saw it on:
        // http://www.codeproject.com/Tips/548945/Generating-Many-to-Many-Relation-in-MVC4-using-Ent
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Timeline>()
                .HasMany(c => c.Users)
                .WithMany(s => s.Timelines)
                .Map(mc =>
                {
                    mc.ToTable("TimelineOwners");
                    mc.MapLeftKey("TimelineId");
                    mc.MapRightKey("UserId");
                });
        }
    }
}

UserProfile クラス (プロパティが追加されたデフォルト クラス):

public class UsersContext : DbContext
{
    public UsersContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<Timeline> Timelines { get; set; }

    // Added the following because I saw it on:
    // http://www.codeproject.com/Tips/548945/Generating-Many-to-Many-Relation-in-MVC4-using-Ent
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<UserProfile>()
            .HasMany(c => c.Timelines)
            .WithMany(s => s.Users)
            .Map (mc =>
                {
                   mc.ToTable("TimelineOwners");
                   mc.MapLeftKey("UserId");
                   mc.MapRightKey("TimelineId");
               });
    }
}

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }

    public List<Timeline> Timelines { get; set; }
}

外部キーを持つ接続テーブルがあります。

ここに画像の説明を入力

ここに画像の説明を入力

ここに画像の説明を入力

のインスタンスを作成する場合TimelineUsersリストはnull次のとおりです。

Timeline timeline = db.Timelines.Find(id); // timeline.Users = null

誰かが私を教えてくれますか?

ASP.NET MVC4 はまったく初めてです。

編集 1: UserProfile を拡張するのではなく、ユーザーを格納する別のクラスを作成する必要があることを理解しています。多対多の関係が機能したら、リファクタリングしてその方向に進みます。しかし、最初に、なぜ機能しないのかを知りたいです。

編集 2: 二重コンテキストも問題を引き起こしました。2 つのコンテキストに対して 2 つのデータベースが作成され、そのうちの 1 つで純粋な結合テーブルが空でした。

4

2 に答える 2

2

Entity Framework を使用してナビゲーション プロパティを読み込む方法については、この記事を参照することをお勧めします。これは、多対多の関係だけでなく、あらゆる種類の関係に重要な非常に基本的な知識です。

その記事を見ると、この行が...

Timeline timeline = db.Timelines.Find(id);

...関連エンティティをロードしません。そのため、エンティティがデータベース内で関連付けられている場合でも、それtimeline.Usersが期待されます。null

をロードしたい場合は、eager loadingUsersを使用できます。

Timeline timeline = db.Timelines.Include(t => t.Users)
    .SingleOrDefault(t => t.Id == id);

これは単一のデータベース クエリです。または、遅延読み込みを有効にするには、ナビゲーション プロパティを次のようにマークする必要がありますvirtual

public virtual List<UserProfile> Users { get; set; }

//...

public virtual List<Timeline> Timelines { get; set; }

その後、元のコードを使用できます。

Timeline timeline = db.Timelines.Find(id); // first query
var users = timeline.Users;                // second query

これにより、2 つの個別のクエリが実行されます。2 つ目は、ナビゲーション プロパティに初めてアクセスするとすぐに実行されます。

ところで: 2 つのコンテキスト クラスがある理由はありTimelineContextますUsersContextか? 「通常」必要なコンテキストは 1 つだけです。

于 2013-06-30T21:17:29.450 に答える
0

私は、内部ユーザー プロファイルの動作をいじるのが好きではありません。独自のユーザー クラスを作成し、それを simplemembershipprovider にリンクして、そこに機能を追加することをお勧めします。最大では、登録するフィールドを追加するために accountclasses を少し拡張しますが、それだけです。

この非常に便利なガイドに従って作業を進め、エラーが発生した場合はお知らせください。

于 2013-06-30T17:40:11.083 に答える