0

EF Code First を使用して ASP.NET MVC4 アプリケーションを開発しています。次のクラス間で多対多の関係があります。コンテキスト クラスで EF fluent API を使用して関係を定義しました。しかし、多対多の関係にあるマスター テーブルの 1 つに値を挿入しようとすると、エラーが発生します。誰でも私の問題を解決するのを手伝ってくれますか? 貴重な時間を割いていただきありがとうございます。リポジトリ パターンと Ninject の作業単位を依存性注入として使用しています。 参加クラス

public class Participant
    {
        [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; }

    }

インタレストクラス

public class Interest
    {
        public int Id { get; set; }
        public string InterestName { get; set; }
        public virtual ICollection<Participant> Participants { get; set; }
    }

DataContext

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(i => i.Participants).
                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);
        }


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

コントローラーコード

public virtual ActionResult Register(StudentRegisterViewModel studentRegisterViewModel)
        {
            if (ModelState.IsValid)
            {
                if (_userService.IsUserExists(studentRegisterViewModel.Participant.User) == false)
                {
                    // Attempt to register the user

                    //WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
                    //WebSecurity.Login(model.UserName, model.Password);
                    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;
                    var participant = new Participant
                    {
                        Id = studentRegisterViewModel.Participant.Id,
                        FirstName = studentRegisterViewModel.Participant.FirstName,
                        LastName = studentRegisterViewModel.Participant.LastName,
                        Interests = new Collection<Interest>()
                    };
                    var interests = new List<Interest>();
                    foreach (var interestItem in studentRegisterViewModel.SelectedInterests)
                    {
                        var interest = new Interest { Id = interestItem, Participants = new Collection<Participant>() };
                        interest.Participants.Add(participant);
                        interests.Add(interest);
                    }
                    studentRegisterViewModel.Participant.Interests = interests;
                    _participantService.CreatParticipant(studentRegisterViewModel.Participant);
                    //_userService.CreatUser(studentRegisterViewModel.Participant.User);
                    //TODO: Need to check if do we need to register the user and get him signed-in. If yes signing in implementation goes here.
                    var user = _userService.GetUser(studentRegisterViewModel.Participant.User.Username);
                    //Session["User"] = user;
                    //FormsAuthentication.SetAuthCookie(user.Username, false);
                    //Growl("Welcome", "Thanks for registering and welcome to Truck Tracker.");
                    //return RedirectToAction("Index", "Home");
                }
            }
            //return RedirectToAction("Index", "Home");
            // If we got this far, something failed, redisplay form
            studentRegisterViewModel.Gender =
                Enum.GetNames(typeof(Gender)).Select(
                    x => new KeyValuePair<string, string>(x, x.ToString(CultureInfo.InvariantCulture)));
            studentRegisterViewModel.Interests = _interestService.GetAllInterests();
            return View(studentRegisterViewModel);
        }

理想的には、参加者を参加者テーブルに挿入し、参加者の関心を多対多テーブルの ParticipantInterests に挿入する必要があります。しかし、次のエラーが発生しています

{"値 NULL を列 'InterestName'、テーブル 'StudyTourNetworkDB.dbo.Interests' に挿入できません。列は NULL を許可しません。INSERT は失敗します。\r\nステートメントは終了しました。"}

起こらないはずの Interests テーブルに挿入しようとしています。

参加者 ParticipantInterests Interests Interests Id Id Id FirstName ParticipantId InterestName LastName InterestId

これは、データベース内のテーブルです。Interest テーブルには、Interested In ドロップダウンに表示されるレコードの固定セット (Study、Job、Other など) があります。登録参加者は複数の興味のあるオプションを選択でき、[サインアップ] ボタンをクリックすると、参加者レコードが参加者テーブルに保存され、選択された興味が ParticipantInterests テーブルに保存されます。

ありがとう

4

1 に答える 1

0

私は先日同じことをいじっていました。それを理解するのは苦痛ですが、これは私が取り組んだ多対多の非常に基本的な例です:

namespace Project.Models
{
    public class Affiliate
    {
        public Affiliate()
        {
            Merchants = new HashSet<Merchant>();
        }
        public int Id { get; set; }
        public ICollection<Merchant> Merchants { get; set; }
    }
}


namespace Project.Models
{
    public class Merchant
    {
        public Merchant()
        {
            Affiliates = new HashSet<Affiliate>();
        }
        public int Id { get; set; }
        public ICollection<Affiliate> Affiliates{ get; set; }
    }
}

そしてDbContextで私はこれをしました:

            modelBuilder.Entity<Merchant>().
              HasMany(c => c.Affiliates).
              WithMany(p => p.Merchants).
              Map(
               m =>
               {
                   m.MapLeftKey("MerchantId");
                   m.MapRightKey("AffiliateId");
                   m.ToTable("MerchantAffiliates");
               });

アップデート

私はあなたが達成しようとしていることを理解しようとしています。次のようです。

参加者は多くのことに興味を持つことができます。複数の参加者が同じことに興味を持つことができます。それが事実である場合、モデルを変更して、参加者が興味のリストを持つようにすることを検討しますが、私の意見では、興味テーブルには参加者のリストは必要ありません。ハイキングに興味のあるすべての参加者を取得したい場合は、次のようにするだけです。

Context.Participants.ToList().Where(x => x.Interest.Name == "hiking");

わかる?

于 2012-12-06T06:12:12.537 に答える