web-dev-qa-db-ja.com

AspNetUsersのIDを別のテーブルの外部キーとして1対1の関係

AspNetUserテーブルの外部キーを別のCustomerテーブルに格納できるようにするために、さまざまな方法を試してみました。 ASP.NETとEntity Frameworkはまだ新しいですが、かなりの数の投稿とドキュメントを読みました。

現在これは私が持っているものです

モデル

public class Customer
{
    [Display (Name="Customer ID")]
    public int CustomerID { get; set; }

    public string UserId { get; set; }
    [ForeignKey("UserId")]
    public virtual ApplicationUser ApplicationUser { get; set; }

}


 public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Customer> Customers { get; set; }

    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

}

私はこのエラーを受け取ります、引用

タイプ 'TestApplication.Models.Customer'と 'TestApplication.Models.ApplicationUser'の間の関連付けの主な終了を判別できません。この関連付けの主な端は、リレーションシップFluent APIまたはデータアノテーションを使用して明示的に構成する必要があります。

私はここにあるこの人の方法も試しました: この関連付けの主要な端は、リレーションシップAPIまたはデータアノテーションを使用して明示的に設定する必要があります

そこで、ForeignKeyアノテーションをコメントアウトし、「modelBuilder」アプローチを使用して、その人の提案を使用しました。データベースを更新すると、AspNetUsersテーブルの 'Id'はCustomersテーブルにありました(これは適切です)が、ForeignKeyとしてのCustomerIDもAspNetUsersテーブルにありました。

私が欲しいのは、AspNetUsersの 'Id'がForeignKeyとしてCustomersテーブルにあることです。

16
JayEz

1対1のリレーションでは、「子」テーブル、つまりCustomerは、関連するテーブルと同じ主キー、つまり外部キーを持つ必要があります。

指定したコードサンプルは、CustomerCustomerIDとは異なるUserIdという名前のPKがあることを意味します。

これはあなたのケースで動作するはずです(テストされていません):

public class Customer
{
    [Key]
    public string UserId { get; set; }

    [ForeignKey("UserId")]
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

編集:

ForeignKeyAttributeのMSDN 状態:

ForeigKey属性を外部キープロパティに追加する場合は、関連するナビゲーションプロパティの名前を指定する必要があります。 ForeigKey属性をナビゲーションプロパティに追加する場合は、関連付けられている外部キーの名前を指定する必要があります。

私はこれを、ForeignKey-attributeをナビゲーションプロパティまたは外部キープロパティのいずれかに追加できるはずであり、どちらの方法も機能するはずであるが、明らかに機能しないと解釈します。以下のように移動するとうまくいくはずです。

public class Customer
{
    [Key, ForeignKey("ApplicationUser")]
    public string UserId { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}
15
Andreas Ågren

私はこの投稿が2歳であることを知っていますが、より良い解決策は、Customerクラスで_[ForeignKey]_属性を使用するのではなく、Fluent APIを使用して外部キーを設定することです。これを行う方法を次に示します。

_public class Customer
{
    public int CustomerID { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext() : base("DefaultConnection")
    {
    }

    public DbSet<Customer> Customers { get; set; }

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

        // one-to-zero or one relationship between ApplicationUser and Customer
        // UserId column in Customers table will be foreign key
        modelBuilder.Entity<ApplicationUser>()
            .HasOptional(m => m.Customer)
            .WithRequired(m => m.ApplicationUser)
            .Map(p => p.MapKey("UserId"));
    }

}
_

これにより、UserIdテーブルへの外部キーであるCustomersテーブルにAspNetUsers列が作成されます。 .Map(p => p.MayKey("UserId"))は省略でき、EFは慣習的に外部キーに_ApplicationUser_Id_という名前を付けます。

6
kimbaudi