我使用EF代码第一种方法,流畅的api。我在我的应用程序中有一个注册表单,其中注册候选人可以从下拉列表中选择多个选项(感兴趣的是注册表单上的下拉列表),这些选项具有一组预定义的选项(将来可能会增加,但机会非常少)。当用户提交表单时,我想将此记录保存到数据库中。所以我创建了以下实体。
将保存注册候选人信息的参与者类
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; }
}
注册表单中感兴趣的下拉列表将会填充的兴趣类 * 用户可以从感兴趣的下拉列表中选择多个选项 *
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; }
和
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';列不允许空值.INSERT失败。\ r \ n语句已终止。”} < / p>
理想情况下,根据我的想法,它应该在参与者表中插入参与者信息,并在参与者兴趣表中插入参与者兴趣。但它试图在Interests表中插入记录,这不应该发生。请帮我解决这个问题。我可能通过创建多对多关联做错了。
由于
答案 0 :(得分:2)
从Id
表中删除ParticipantInterests
列,并使ParticipantId
和InterestId
成为复合主键。把它们留作外键。
将您的多对多映射更改为...
//...
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
可用。但希望你能得到这个想法。