0

流暢なAPIでEFコードファーストアプローチを使用しています。アプリケーションに 1 つの登録フォームがあり、候補者を登録する際に、事前定義された一連のオプションを持つドロップダウン (サインアップ フォームのドロップダウンに興味がある) から複数のオプションを選択できます (将来的に増加する可能性がありますが、可能性は非常にまれです)。ユーザーがフォームを送信すると、このレコードをデータベースに保存したいと思います。そこで、次のエンティティを作成しました。

参加者 登録候補者情報が保存されるクラス

public class Participant
    {
        public Participant()
        {
            Interests = new Collection<Interest>();
        }
        [Key]
        public int Id { get; set; }
        [DisplayName("First Name")]
        [StringLength(50, ErrorMessage = "First name cannot be more than 50 characters")]
        [Required(ErrorMessage = "You must fill in first name")]
        public string FirstName { get; set; }

        [DisplayName("Last Name")]
        [StringLength(50, ErrorMessage = "Last name cannot be more than 50 characters")]
        [Required(ErrorMessage = "You must fill in last name")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "You must indicate your full birthday")]
        [DisplayName("Birthday")]
        [DataType(DataType.DateTime)]
        public DateTime BirthDate { get; set; }

        [DisplayName("Gender")]
        [Required(ErrorMessage = "You must select gender")]
        public int Gender { get; set; }

        public string Address { get; set; }

        public int CountryId { get; set; }
        public Country Country { get; set; }

        [DisplayName("Zip code")]
        [StringLength(10, ErrorMessage = "Zip code cannot be more than 10 characters")]
        public string ZipCode { get; set; }

        public string Mobile { get; set; }

        public string PhotoUrl { get; set; }

        public int UserId { get; set; }
        public User User { get; set; }

        public virtual ICollection<Interest> Interests { get; set; }
}

サインアップ フォームの [Interested In] ドロップダウンが入力されるインタレスト クラス *ユーザーは [Interested In] ドロップダウンから複数のオプションを選択できます*

public class Interest
    {
        public Interest()
        {
            Participants = new Collection<Participant>();
        }
        public int Id { get; set; }
        public string InterestName { get; set; }
        public virtual ICollection<Participant> Participants { get; set; }
    }

各参加者の関心を保持するために、次のスキーマを使用して DB に ParticipantInterests テーブルを作成しました。 ParticipantInterests Id (PK) ParticipantId (参加者テーブルからの FK) InterestId (FK 興味テーブル)

public virtual ICollection<Participant> Participants { get; set; }私はInterestモデルに追加し、

public virtual ICollection<Interest> Interests { get; set; } in Participant model to form Many-To-Many association.

私のデータコンテキストクラスは次のとおりです

public class STNDataContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<Participant> Participants { get; set; }
        public DbSet<Country> Countries { get; set; }
        public DbSet<Interest> Interests { get; set; }
        public DbSet<Role> Roles { get; set; }
        public DbSet<SecurityQuestion> SecurityQuestions { get; set; }

        public DbSet<Tour> Tours { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Participant>().
                HasMany(p => p.Interests).
                WithMany().
                Map(
                    m =>
                    {
                        m.ToTable("ParticipantInterests");
                        m.MapLeftKey("ParticipantId");
                        m.MapRightKey("InterestId");
                    });
            modelBuilder.Entity<User>().HasRequired(u => u.Role);
            modelBuilder.Entity<Participant>().HasRequired(p => p.Country);
            modelBuilder.Entity<Participant>().HasRequired(p => p.Interests);
        }


        public virtual void Commit()
        {
            base.SaveChanges();
        }
    }

コントローラ アクション コード

public virtual ActionResult Register(StudentRegisterViewModel studentRegisterViewModel)
        {
if (ModelState.IsValid)
            {
                if (_userService.IsUserExists(studentRegisterViewModel.Participant.User) == false)
                {
                    studentRegisterViewModel.Participant.User.Username = studentRegisterViewModel.Username;
                    studentRegisterViewModel.Participant.User.Email = studentRegisterViewModel.Email;
                    studentRegisterViewModel.Participant.User.DateCreated = DateTime.Now;
                    studentRegisterViewModel.Participant.User.Id = 3;
                    studentRegisterViewModel.Participant.User.IsApproved = false;
                    studentRegisterViewModel.Participant.User.RoleId = 2;
                    studentRegisterViewModel.Participant.CountryId = 1;
                    foreach (var interestItem in studentRegisterViewModel.SelectedInterests)
                    {
                        var interest = new Interest { Id = interestItem};
                        studentRegisterViewModel.Participant.Interests.Add(interest);
                    }

                    _participantService.CreatParticipant(studentRegisterViewModel.Participant);

                }
            }


            studentRegisterViewModel.Gender =
                Enum.GetNames(typeof(Gender)).Select(
                    x => new KeyValuePair<string, string>(x, x.ToString(CultureInfo.InvariantCulture)));
            studentRegisterViewModel.Interests = _interestService.GetAllInterests();
            return View(studentRegisterViewModel);
        }

参加者を作成しようとすると、次のエラーが発生します。 {"値 NULL を列 'InterestName'、テーブル 'StudyTourNetworkDB.dbo.Interests' に挿入できません。列は NULL を許可しません。INSERT は失敗します。\r\nステートメントは終了しました。"}

理想的には、私の考えでは、参加者テーブルに参加者情報を挿入し、参加者インタレストテーブルに参加者の関心を挿入する必要があります。しかし、Interests テーブルにもレコードを挿入しようとしていますが、これは起こるべきではありません。この問題の解決を手伝ってください。多対多の関連付けを作成することで間違っている可能性があります。

ありがとう

4

1 に答える 1

2
  • テーブルIdから列を削除し、複合主キーを作成します。それらを外部キーのままにしておきます。ParticipantInterestsParticipantIdInterestId

  • 多対多マッピングを次のように変更します...

    //...
    HasMany(p => p.Interests).
    WithMany(i => i.Participants).
    //...
    

    ...そして、このマッピング行を削除します:

    modelBuilder.Entity<Participant>().HasRequired(p => p.Interests);
    
  • 関心をコンテキストにアタッチして、EF が挿入を試みないようにします。

    foreach (var interestItem in studentRegisterViewModel.SelectedInterests)
    {
        var interest = new Interest { Id = interestItem};
        context.Interests.Attach(interest);
        studentRegisterViewModel.Participant.Interests.Add(interest);
    }
    

    インタレストをコンテキストに関連付ける行をサービス クラスに追加する必要があります。コントローラーに利用可能ながないと思いますcontext。しかし、うまくいけば、あなたはアイデアを得るでしょう。

于 2012-12-06T17:15:01.173 に答える