更新身份用户记录将为导航项创建新记录

时间:2019-05-20 15:36:06

标签: c# entity-framework-6 asp.net-identity

我有一个带有身份的“相当标准”的实体框架,在其中我为用户地址添加了外键导航属性。当我来更新记录时,地址项将再次添加,并在数据库中添加一个新的自动递增ID。

在这个杰出的论坛的其他地方,我看到它可能是由两个数据库上下文引起的,但我不认为我有这个问题(但也许找不到),并尝试了在那里提出的解决方案: UserManager updating a user record but creating a new record as well。 这里有一些历史,它始于两个数据库上下文,但是我(我想)将它们组合为一个,因为不需要两个。 这是主要的更新功能:(注意:我从另一个SO问题中删除了我尝试的修复程序。)

    // POST api/Account/UpdateUserDetail
    [Route("UpdateUserDetail")]
    public async Task<IHttpActionResult> UpdateUserDetail(SGGUserDTO usertoupdate)
    {
        //using (SGGContext ctx = new SGGContext())
        //{
        //    ApplicationUserManager UserManager = new ApplicationUserManager(new UserStore<SGGUser>(ctx));
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            string userid = User.Identity.GetUserId(); //Check user is valid
            if (usertoupdate.Id != userid)
            {
                return NotFound();
            }
            SGGUser user = await UserManager.FindByIdAsync(userid);
            if (user == null)
            {
                return NotFound();
            }
            Mapper.Map(usertoupdate, user);
            var result = await UserManager.UpdateAsync(user);
            if (result.Succeeded)
            {
                return Ok();
            }
            else
            {
                return GetErrorResult(result);
            }
        //}

    }

update方法位于API控制器中,其初始化如下所示:

    public class AccountController : ApiController
{
    private const string LocalLoginProvider = "Local";
    private SGGContext db = new SGGContext();
    private ApplicationUserManager _userManager;
    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager,
        ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
    {
        UserManager = userManager;
        AccessTokenFormat = accessTokenFormat;
    }

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

我的身份模型如下:

    public class SGGUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<SGGUser> manager, string authenticationType = DefaultAuthenticationTypes.ApplicationCookie)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
        // Add custom user claims here
        return userIdentity;
    }

    [Display(Name = "Date of Birth")]
    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:d}",
        NullDisplayText = "Please Enter Your Date of Birth",
        ApplyFormatInEditMode = true)]

    public DateTime? DateOfBirth { get; set; }
    public string Title { get; set; }
    public string FirstName { get; set; }

    .... bunch of stuff

    public Address Address { get; set; }
    public virtual BusinessUser BusinessUser { get; set; }
    public virtual BusinessCustomer BusinessCustomer { get; set; }

    .... bunch more stuff
}

ApplicationUserManager是这样的:

    public class ApplicationUserManager : UserManager<SGGUser>
{
    public ApplicationUserManager(IUserStore<SGGUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var  db = new SGGContext();
        var manager = new ApplicationUserManager(new UserStore<SGGUser>(context.Get<SGGContext>()));

        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<SGGUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {

  .... Bunch more stuff
            return manager;
    }

...,数据库上下文(SGGContext)如下所示:

    public class SGGContext : IdentityDbContext<SGGUser>
{
    public SGGContext()
        : base("SGGContext", throwIfV1Schema: false)
    {
    }

    static SGGContext()
    {
        Database.SetInitializer(new sggDbInitializer_on_change());
    }

    public static SGGContext Create()
    {
        return new SGGContext();
    }

    public DbSet<Address> Addresses { get; set; }

    public DbSet<Business> Businesses { get; set; }

    .... bunch more things

}

说实话,我认为所有漂亮的样板东西。

但是当我使用地址更新记录时,用户可以很好地进行更新,但是地址对象添加了一条新记录。 我也确实在此处找到另一篇关于SO的文章:EF record update creates new record for related object  并且我确实尝试使用.Attach,但是由于它引发了错误,我担心我无法使它正常工作。

有人能发现我不经意间有两种情况或发现问题吗? 非常感谢。

0 个答案:

没有答案