Я пытаюсь добавить сущность ApplicationUser
и Person
в мой контекст
Мой ApplicationUser
класс
public class ApplicationUser : IdentityUser<Guid>
{
public int? PersonID { get; set; }
[ForeignKey("PersonID")]
public Person Person { get; set; }
[InverseProperty("User")]
public ICollection<UserSource> UserSources { get; set; }
public virtual ICollection<IdentityUserClaim<Guid>> Claims { get; set; }
public virtual ICollection<IdentityUserLogin<Guid>> Logins { get; set; }
public virtual ICollection<IdentityUserToken<Guid>> Tokens { get; set; }
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
}
Мой Person
класс
public class Person : BaseEntity
{
[Required]
[DataType(DataType.Text)]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
public string LastName { get; set; }
[Required]
[DataType(DataType.Text)]
public string FullName { get; set; }
public int HeightInches { get; set; }
public int WeightPounds { get; set; }
[DataType(DataType.Text)]
public string BatHand { get; set; }
[DataType(DataType.Text)]
public string ThrowHand { get; set; }
public DimDate BirthDate { get; set; }
public DimDate DeathDate { get; set; }
public DimDate DebutDate { get; set; }
public DimDate FinalDate { get; set; }
public Guid? UserID { get; set; }
[ForeignKey("UserID")]
public ApplicationUser User { get; set; }
[InverseProperty("LeagueOwner")]
public ICollection<League> LeaguesOwned { get; set; }
public override int GetHashCode() => Tuple.Create(this.FirstName, this.LastName, this.FullName).GetHashCode();
}
Я пытаюсь создать обе эти сущности, а затем объединить их ie в методе RegisterUser
моего UserService
Public Class UserService : IUserService
{
private MyDbContext context;
private ILogger logger;
private UserManager<ApplicationUser> userManager;
public async Task<ApplicationUser> RegisterUser(RegistrationModel registrationModel)
{
// Create the User first
var user = new ApplicationUser
{
UserName = registrationModel.UserName,
Email = registrationModel.Email
};
// Create the User with a password
var result = await this.userManager.CreateAsync(user, registrationModel.Password);
// Make sure the user is successfully created
if (result.Succeeded)
{
try
{
this.logger.LogInformation($"User {user.UserName} successfully created and added to the database");
// create a person for the User (this is causing me to have a headache...)
// I originally had this is separate methods... moving into one so I can make more sense
var fullName = (registrationModel.FirstName == registrationModel.LastName) ? registrationModel.FirstName : registrationModel.FirstName + " " + registrationModel.LastName;
var newPerson = new Person
{
FirstName = registrationModel.FirstName,
LastName = registrationModel.LastName,
FullName = fullName
};
// Add the person to the DB
await this.context.People.AddAsync(newPerson);
// Add the User to the Person and vice versa
user.Person = newPerson;
newPerson.User = user;
// Save the changes
await this.context.SaveChangesAsync();
this.logger.LogInformation($"Person for {user.NormalizedUserName} created");
// Add source to the user
var userSource = new UserSource
{
MySource = registrationModel.WhereDidYouHear,
User = user
};
await this.context.UserSources.AddAsync(userSource);
this.logger.LogInformation($"Source added to UserSources for {user.NormalizedUserName}");
return user;
}
catch (Exception e)
{
this.logger.LogError(e);
return null;
}
}
foreach (var error in result.Errors)
{
this.logger.LogError(error.Description);
}
return null;
}
}
Однако, когда этот метод выполняется, В моем журнале появляется следующая ошибка:
System.InvalidOperationException: невозможно сохранить изменения, поскольку в данных, подлежащих сохранению, обнаружена циклическая зависимость: 'Person [Added] <- Person {' PersonID '} ApplicationUser [Добавлено] <- Пользователь {' UserID '} Person [Добавлено]' </p>
Насколько я знаю, я думаю У меня установлены отношения правильно между ApplicationUser
и Person
, поэтому я не уверен, почему он не позволяет мне прикрепить Person
к ApplicationUser
и наоборот.
Я включу RegistrationModel
для справки, поскольку данные в нем используются в RegisterUser
Методе:
public class RegistrationModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[RegularExpression(@"^[a-zA-Z0-9_]{5,255}$")]
[Required]
[StringLength(256)]
[Display(Name = "UserName")]
public string UserName { get; set; }
[Required]
[StringLength(256)]
public string FirstName { get; set; }
[Required]
[StringLength(256)]
public string LastName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[DataType(DataType.Text)]
[Display(Name = "Where did you hear about us?")]
public string WhereDidYouHear { get; set; }
}