5

この質問: Ef Many To Manyでは、リンク テーブルを手動で指定する方法について回答がありました。しかし、私には少し特殊な状況があります (これは本当に特殊なことではないと確信しています)。

私の 2 つのテーブルにはそれぞれ Id フィールドがあります。例:[dbo].[Account].[Id][dbo].[Person].[Id]. 私の Code-First のこれらの各テーブルには、次の OnModelCreating があります。

modelBuilder.Entity<Account>.HasKey(x => x.Id);
modelBuilder.Entity<Person>.HasKey(x => x.Id);

しかし、私の[dbo].[AccountsToPersons]...テーブルにはフィールド EG:[AccountId][PersonId]

AccountsToPersons テーブルは、コード内のクラスによって表されません。

私は明らかに既存のモデルを持っていますが、データベースからモデルを更新する代わりに、EF Code-First Fluent API を使用しています。

では、このコードを変更して、異なる ID 列名のマッピングで機能するようにするにはどうすればよいでしょうか?

public DbSet<Person> Persons { get; set; }
public DbSet<Account> Accounts { get; set; }
. . .
modelBuilder.Entity<Account>()
  .HasMany(a => a.Persons)
  .WithMany()
  .Map(x =>
  {
    x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId??
    x.MapRightKey("PersonId"); // <-- Person.Id  to AccountsToPersons.PersonId??
    x.ToTable("AccountsToPersons");
  });

基本的な Linq To EF Query を実行する(from x in context.Accounts select x).ToList();と、クエリは次のエラーで失敗します。

  • 「列名 'Person_Id' が無効です。」

しかし、 Query を実行して(from x in context.Persons select x).ToList();もエラーは発生しません。

基本的な型付けされた列以外に、私のモデルにはこれらが追加されています。

// In my Account Model, I also have this property:
public IList<Person> Persons { get; set; }

// In my Person Model, I also have this property:
public IList<Account> Accounts { get; set; } // <-- in the Person model

また、Accounts クエリがパスしてフィールド情報が含まれている場合でも、テーブルPersonsにリンクがあると確信していても、フィールドは常に null であることに注意してください。AccountsToPersons

4

3 に答える 3

2

私はちょうどあなたの問題のテスト ソリューションを構築しました。

あなたが私と違うことをしたと私が思うことの1つは、次のとおりです。

public IList<Person> Persons { get; set; } // <-- in the Account model
public IList<Account> Accounts { get; set; } // <-- in the Person model

これに変更してみてください:

public DbSet<Person> Persons { get; set; }
public DbSet<Account> Accounts { get; set; }

これが機能しない場合は、セットアップ全体を投稿します。

私の構造は次のようになり、表示したクエリで機能します。

public class Person
{
    public int ID { get; set; }

    public string Name { get; set; }

    public IList<Account> Accounts { get; set; }
}

public class Account
{
    public int ID { get; set; }

    public string Name { get; set; }

    public IList<Person> Persons { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Account> AccountSet { get; set; }

    public DbSet<Person> PersonSet { get; set; }

    public ApplicationDbContext()
        : base("DefaultConnection")
    {
        this.Database.Log = (msg) => { Debug.Write(msg); };
    }

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

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Account>().HasKey(x => x.ID);
        modelBuilder.Entity<Person>().HasKey(x => x.ID);

        modelBuilder.Entity<Account>()
            .HasMany(a => a.Persons)
            .WithMany()
            .Map(w =>
            {
                w.MapLeftKey("AccountId");
                w.MapRightKey("PersonId");
                w.ToTable("AccountsToPersons");
            });
    }
}
于 2014-11-24T20:50:24.990 に答える
0

AccountsToPersons マッピングを少し変更してみましたか:

 modelBuilder.Entity<Account>()
   .HasMany(a => a.Persons)
   .WithMany(p => p.Accounts) <-- Change
   .Map(x =>
    {
         x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId??
         x.MapRightKey("PersonId"); // <-- Person.Id  to AccountsToPersons.PersonId??
         x.ToTable("AccountsToPersons");
    });
于 2014-11-24T21:19:44.000 に答える